【问题标题】:PDO Transactions Locks?PDO 事务锁?
【发布时间】:2012-08-21 15:16:49
【问题描述】:

我通过 PHP PDO 接口对 MySQL 事务进行了广泛的研究。我对事务方法的实际背景工作仍然有些模糊。具体来说,我需要知道是否有任何理由要阻止从脚本开头到结尾的事务中的所有查询(包括选择)?当然,处理事务中的任何错误并在需要时回滚它们。

我想知道在事务期间是否有任何锁定,如果有,是否是行级锁定,因为它是 InnoDB?

【问题讨论】:

  • 我不是专家,所以会发表评论而不是回答,但我认为这取决于您在交易中所做的事情。如果您要更新单行,则该行将被锁定。如果您要删除一个表,该表将是(假设底层提供程序支持它)拥有单个页面长事务的缺点是明显您锁定的任何内容都会导致其他页面等待,从而有效地使您的服务器单线程如果它正在做很多需要锁的工作。

标签: php mysql transactions pdo innodb


【解决方案1】:

不要那样做。

这样做的原因是事务利用MVCC 一种机制,通过该机制,每条更新的数据实际上都不是就地更新,而只是插入到其他地方。

MVCC 意味着分配内存和/或存储空间来累积和操作您发送的所有更改,而不会将它们提交到磁盘,直到您发出 COMMIT

这意味着当您的整个脚本运行时,所有更改都会存储到脚本结束。并且您在事务期间尝试和更改的所有记录都被标记为“正在进行中”,以便其他进程/线程可以知道这些数据很快就会失效。

在脚本的整个长度中将某些数据标记为“正在进行中”意味着任何其他并发更新都会看到该标志并说“我必须等到这完成,所以我会得到最新的数据”。

这包括SELECTS,具体取决于隔离级别。选择标记为“正在进行中”的内容可能不是您想要的,因为您可能想要加入的某些表可能包含已更新的数据,而其他表尚未更新,从而导致脏读。

操作的事务性和原子性是可取的,但代价高昂。在需要的地方使用它。是的,这意味着您需要做更多的工作来确定可能发生竞态条件的位置,即使出现竞态条件,您也必须决定它们是否真的很关键,或者“某些”数据丢失/混合是否可以接受。

您是否希望您的日志、访问计数器和其他统计数据降低整个网站的速度?或者信息的质量是否可以牺牲速度(只要它不是分析套装,您就可以承受偶尔的碰撞)。

您是否希望一个座位预订应用程序在座位数为 0 后仍然无法启动并允许更多用户抢到座位?当然不是——在这里你想利用事务和隔离级别来确保永远不会发生。

【讨论】:

  • 您说的是出于数据一致性的原因使用它,我说的是从纯粹的性能角度使用它。数据一致性是使用事务的一个很好的好处。在事务之外的每个查询更新/插入上花费 50 毫秒是非常慢的,并且会阻碍网站上的快速体验。我想我需要重新考虑一下程序的架构。
  • 所以您建议让脚本运行时间稍长一些,以确保数据库操作尽可能快地发生并且对其他页面加载的影响尽可能小?差不多,自动提交每次更新或插入?
  • 不,我建议您仅将事务与需要它们的更新一起使用。 (单表更新本质上是原子的,顺便说一句)。例如从 1 个或多个表中读取数据并将数据写入 1 个或多个表的复杂更新。在大多数选择上使用它是没有用的。过度插入没用。
  • 所以不要在脚本开头开始事务。并且不要在脚本末尾结束它。如果您不了解它的工作原理以找出您需要它的地方,请根本不要使用它。在您阅读内容的地方使用它处理内容然后更新内容。
  • @MihaiStancu 您提到的大部分内容都是最佳实践,建议您遵循它们。然而,还应注意事务可用于提高插入和更新语句的性能。例如,如果您正在执行多个插入/更新,最好在单个事务中运行它们,这样您就可以避免将每个语句的数据写入磁盘以及调整索引。在此处阅读更多内容以了解插入/更新的工作原理dev.mysql.com/doc/refman/5.1/en/commit.html。还要检查这个 http://:goo.gl/NOJni。
猜你喜欢
  • 2012-04-26
  • 2013-03-25
  • 2014-06-19
  • 2012-07-08
  • 1970-01-01
  • 2011-09-20
  • 2011-01-26
  • 2016-04-13
  • 2016-09-30
相关资源
最近更新 更多