Jes*_*sse 5 mysql sql deadlock innodb mariadb
我有一张简单的桌子
CREATE TABLE test (
col INT,
data TEXT,
KEY (col)
);
Run Code Online (Sandbox Code Playgroud)
和一个简单的交易
START TRANSACTION;
SELECT * FROM test WHERE col = 4 FOR UPDATE;
-- If no results, generate data and insert
INSERT INTO test SET col = 4, data = 'data';
COMMIT;
Run Code Online (Sandbox Code Playgroud)
我试图确保同时运行此事务的两个副本导致没有重复行和没有死锁.我也不想承担发电成本data的col = 4不止一次.
我试过了:
SELECT ..(没有FOR UPDATE或LOCK IN SHARE MODE):
两个事务都看到没有行col = 4(没有获取锁),并且生成data和插入行的两个副本col = 4.
SELECT .. LOCK IN SHARE MODE
两个事务都获取共享锁col = 4,生成data并尝试插入行col = 4.两个事务都等待另一个事务释放它们的共享锁,因此它可以INSERT导致ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction.
SELECT .. FOR UPDATE
我希望一个交易SELECT成功并获得一个独占锁定,col = 4另一个交易SELECT将阻止等待第一个交易.
相反,两个SELECT .. FOR UPDATE查询都成功,事务就像使用一样进入死锁状态SELECT .. LOCK IN SHARE MODE.独家锁定col = 4似乎不起作用.
如何在不导致重复行且没有死锁的情况下编写此事务?
稍微调整一下你的架构:
CREATE TABLE test (
col INT NOT NULL PRIMARY KEY,
data TEXT
);
Run Code Online (Sandbox Code Playgroud)
作为col主键,它不能重复。
然后使用该ON DUPLICATE KEY功能:
INSERT INTO test (col, data) VALUES (4, ...)
ON DUPLICATE KEY UPDATE data=VALUES(data)
Run Code Online (Sandbox Code Playgroud)