MySQL transactions and concurrent inserts

[亡魂溺海] 提交于 2019-12-12 05:49:52

问题


I've got this script made by someone and I looked over it and found something I'm not sure is safe:

Inside a transaction there are 2 consecutive inserts, in 2 different tables, both with auto incremented primary keys. They are supposed to be the same (the primary key generated from the first insert = the primary key generated from the second insert).

Don't ask me why, it's just how the script was made.

I'm new to transactions and I can't quite figure out if there is a concurrency issue here. I am thinking about the possibility of another thread running in the same time and ending up with keys being generated something like:

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

I'm pretty sure (I've only ready transaction-related documentation today for the first time) that a transaction would not protect against this, but I just want to be sure I got it right.

Thanks!


回答1:


You need to put both connections in serializable transaction isolation level in order to avoid the scenario you are describing, either by setting the tx_isolation on each connection with:

SET @@tx_isolation = SERIALIZABLE;

or

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

or by setting the global isolation level with:

SET @@global.tx_isolation = SERIALIZABLE;

or

SET GLOBAL TRANSACTION ISOLATION LEVEL SERIALIZABLE;

which is inherited by any subsequently opened connection. At that level, transactions will block on any queries if another transaction is already in progress, ie. a transaction has already emitted a query (read or write) on the same tables.

See the mysql documentation for further details.




回答2:


Your scenario is definitely possible.

If the primary keys are supposed to be the same in both tables, you may override the AUTO_INCREMENT in the second table and explicitly insert the value:

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


来源:https://stackoverflow.com/questions/16041664/mysql-transactions-and-concurrent-inserts

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!