MySQL事务和并发插入

时间:2013-04-16 15:57:16

标签: mysql concurrency insert transactions isolation

我有一个人制作的这个剧本,我查看了它并发现了一些我不确定是安全的:

在一个事务中,在2个不同的表中有2个连续插入,两个表都有自动递增的主键。它们应该是相同的(从第一个插入生成的主键=从第二个插入生成的主键)。

不要问我为什么,这就是脚本是如何制作的。

我是新手,我无法弄清楚这里是否存在并发问题。我正在考虑另一个线程在同一时间运行的可能性,最后生成的键如下:

Thread #1:    Table_A ID: 3                                        Table_B ID: 4
Thread #2:                      Table_A ID: 4     Table_B ID: 3

我很确定(我今天第一次只准备好与事务相关的文档)交易无法防范这种情况,但我只是想确保我做对了。

谢谢!

2 个答案:

答案 0 :(得分:1)

您需要将两个连接放在可序列化的事务隔离级别中,以避免您描述的场景,方法是在每个连接上设置tx_isolation

SET @@tx_isolation = SERIALIZABLE;

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

或通过以下方式设置全局隔离级别:

SET @@global.tx_isolation = SERIALIZABLE;

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

由任何后续打开的连接继承。在该级别,如果另一个事务正在进行中,事务将阻止任何查询,即。事务已经在相同的表上发出了查询(读或写)。

有关详细信息,请参阅the mysql documentation

答案 1 :(得分:0)

您的情况绝对可能。

如果两个表中的主键应该相同,则可以覆盖第二个表中的AUTO_INCREMENT并显式插入值:

INSERT
INTO    a (id)
VALUES  (NULL) -- this inserts an auto incremented value

INSERT
INTO    b (id)
SELECT  LAST_INSERT_ID() -- this inserts the last value inserted into a in this session