MySQL事务时序

时间:2014-01-17 01:46:27

标签: php mysql sql transactions

我有使用PHP和MySQL的经验,我知道关于 交易,但使用它们的经验相当少。

我正在开发一个Web应用程序,用户将在/向单个数据库进行/执行各种CRUD操作。 (是的,它是InnoDB)。而且我很好奇交易将如何表现,我会给你一个相当简单的例子:

1。)用户1开始一项交易,将我的数据库中John Smith的名称更新为Johnathon Smith

2。)用户2开始一个事务,在用户1的交易开始之后,但在它已经委托之前,读取John Smith 的名称。< / p>

用户2会看到什么结果? JohnJohnathon

在用户1的交易过程中,John Smith的记录是锁定的,还是可以在交易过程中读取?

此外,这两个交易的时间如何运作?用户2的交易是否在某个队列中等待,直到用户1的交易完全结束? MySQL DB如何分析试图访问同一个表/记录的多个事务?

另一个,也就是说,用户1的交易操作平均需要500毫秒才能完成,而用户2的交易操作平均需要750毫秒才能完成。用户2有多长的响应时间? 1250毫秒?

非常感谢任何相关文章或其他SO问题的链接!

1 个答案:

答案 0 :(得分:2)

它的默认工作方式是用户2看到John Smith,直到用户1提交并且用户2启动事务。

换句话说,默认事务隔离称为REPEATABLE-READ。也就是说,InnoDB假设用户2希望看到数据库与用户2启动其当前事务时的状态相同。即使其他人更新数据并提交更新,用户2仍希望查看原始数据,直到他明确刷新数据库的“视图”。

MySQL解决这个问题的方法是保留更新行的两个版本。带有Johnathon Smith的“当前”版本具有指向该行的先前版本的内部指针。 InnoDB将检查这些版本,确定用户2是否应该能够看到当前版本,如果没有,请按照指向先前版本的指针。这是逐行自动完成的。

用户2的交易没有理由等待,这就是“读者不会阻止编写者,反之亦然”。这是多版本并发控制(MVCC)功能的好处,它在很多RDBMS产品中都有类似的实现,如Oracle,PostgreSQL和Firebird。

一旦用户1提交了他的更改,并且没有仍在运行的事务需要查看该行的先前版本,InnoDB有一个后台线程,可以逐步清理那些旧版本。

这对于报告想要运行多个查询并希望所有小计都匹配的应用程序非常重要。如果报告中的后一个查询看到了稍微更新的数据库视图,则它们可能会得到与早期查询不同的结果。

您可以选择将事务隔离级别更改为READ-COMMITTED,这样用户2将自动刷新数据库的“视图”,以查看更新的名称Johnathon Smith(原文如此),但只有用户1提交之后。如果用户1尚未提交,则用户2无法看到更改。

您甚至可以将事务隔离级别更改为READ-UNCOMMITTED,因此用户2甚至可以在用户1提交之前查看更新。但这很少是你想要做的 - 用户1可以回滚,因为Johnathon显然是Jonathan的拼写错误。

你可以尝试自己测试所有这些,打开两个运行mysql客户端的shell窗口,然后在它们之间来回跳转,看看变化从一个会话到另一个会话是如何可见的。

您需要了解如何使用SET TRANSACTION语句更改每个会话的事务隔离级别。

另见: