mysql 并发死锁_Mysql并发更新导致死锁
发布日期:2021-06-24 13:16:30 浏览次数:2 分类:技术文章

本文共 2236 字,大约阅读时间需要 7 分钟。

将mysql 5.7与存储引擎一起用作innodb . 我有一个存储产品信息的表 . 该表在productId上使用唯一键看起来像这样

| Field | Type | Null | Key | Default | Extra |

+-----------+--------------+------+-----+-------------------+-----------------------------+

| id | bigint(20) | NO | PRI | NULL | auto_increment |

| productId | varchar(50) | NO | UNI | NULL | |

| seller | varchar(100) | NO | MUL | NULL | |

| updatedAt | timestamp | NO | MUL | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |

| status | varchar(100) | NO | MUL | NULL | |

| data | longtext | NO | | NULL | |

+-----------+--------------+------+-----+-------------------+-----------------------------+

我通过连接到这个mysql的java应用程序进行了两次操作:

1.如果productId的版本大于现有事件,则需要插入新的传入事件(包含有关产品更改的信息) . 该版本在我的数据列中存储为json blob

2.更新productId的行以更改状态 .

我的隔离级别是读取提交的 . 我尝试了两种方法,但都导致了死锁:

Approach1:

Transaction1 starts

Insert ignore into products where productId='X' values(); // Takes a S lock on the row

select * from products where productId='X' for update ; // Take a X lock on the row to prevent new writes and compare the incoming event with the current event

Insert into products values on duplicate key update values // insert into row and on duplicate key update values

commit

并发更新将打开另一个事务:

Transaction2 starts

select * from products where productId='X' for update ; // Take a X lock on the row to prevent new writes and compare the incoming event with the current event

Insert into products values on duplicate key update values // insert into row and on duplicate key update values

commit;

这导致以下情况陷入僵局:

1.事务1 - 插入ignore语句对该行进行了S锁定 .

2.事务2 - 选择更新语句正在等待对该行进行X锁定 .

3.事务1 - 选择更新语句尝试对该行进行X锁定 .

这会导致死锁,因为事务1正在保持S锁,而事务2正在等待进入X锁,而当事务1尝试进行X锁时,会导致死锁 .

方法2:

Transaction 1 starts:

select * from products where productId='X' for update ; // If a row exists then it will be locked else I know it does not exist

Insert ignore into products where productId='X' values();

commit

Transaction 2 starts:

select * from products where productId='X' for update ; // If a row exists then it will be locked else I know it does not exist

commit

这导致以下情况陷入僵局:

1.事务1 - 选择更新语句对行进行X锁定 .

2.事务2 - 选择更新语句正在等待对该行进行X锁定 .

3.事务1 - 插入ignore语句尝试对该行进行S锁定,但事务1的X锁定已经在等待导致死锁的锁定

所以,我想知道如何处理并发更新并将新事件(而不是行更新)插入到我的表中而不会导致死锁 .

1.锁定顺序应该是什么?

2.如何确保并发更新和新行插入在没有死锁的情况下工作 .

任何帮助,将不胜感激 :)

转载地址:https://blog.csdn.net/weixin_33073525/article/details/113439868 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:mysql 用户表记录表_MYSQL库,表,记录的基本操作
下一篇:anchors如何获得_YOLOv3 K-means获取anchors大小

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月21日 12时37分16秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章