MYSQL事务同时修改单条记录
-
疑问:Mysql多事务默认情况下,同时修改同一条记录运行修改吗?是否要手动加上for update行锁。
-
猜想:MySQL 会自动对涉及的数据行加上写锁(排他锁),以确保数据的一致性和隔离性。这是在默认的事务隔离级别 Repeatable Read 下的行为。
-
验证
第一个事务不结束,并对message_id=40的记录进行修改
BEGIN;
UPDATE message SET message_name = '瓜瓜在哪里' WHERE message_id = 40;
SELECT * FROM message WHERE message_id = 40;
第二个事务同样执行,对该记录进行修改
BEGIN;
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40;
SELECT * FROM message WHERE message_id = 40;
COMMIT;
- 结果
第二个事务,一直处于阻塞状态,知道我42秒将第一个事务COMMIT后,才获得锁进行修改操作。
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40
> Affected rows: 1
> 时间: 42.577s
- 结论
在多事务同时修改同一条记录的情况下,MySQL 会自动对涉及的数据行加上写锁(排他锁)。
注意:读该条记录的话不受影响。 不是事务,进行修改同一条也会阻塞。
- 引出问题:那么自动也可以加锁的话,我怎么验证手动加锁for update是否生效,因为它不手动加锁,也会自动加锁阻止update。
- 测试1:于是想到不结束的事务,不作修改就不会自动加锁。
第一个事务只做查询
BEGIN;
SELECT * FROM message WHERE message_id = 40;
第二个事务对该记录进行修改,查看是否阻塞
BEGIN;
SELECT * FROM message WHERE message_id = 40;
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40;
SELECT * FROM message WHERE message_id = 40;
COMMIT;
BEGIN
> OK
> 时间: 0.016s
SELECT * FROM message WHERE message_id = 40
> OK
> 时间: 0.02s
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40
> Affected rows: 0
> 时间: 0.016s
SELECT * FROM message WHERE message_id = 40
> OK
> 时间: 0.018s
COMMIT
> OK
> 时间: 0.017s
-
结论:发现不会阻塞正常修改。
-
测试2:对查询手动加排它锁,FOR UPDATE,其他事务对该记录进行修改,查看是否阻塞。
第一个事务对查询手动加排它锁,FOR UPDATE
BEGIN;
SELECT * FROM message WHERE message_id = 40 for UPDATE;
SELECT * FROM message WHERE message_id = 40;
第二个事务对该记录进行修改
BEGIN;
SELECT * FROM message WHERE message_id = 40;
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40;
SELECT * FROM message WHERE message_id = 40;
COMMIT;
BEGIN
> OK
> 时间: 0.015s
SELECT * FROM message WHERE message_id = 40
> OK
> 时间: 0.016s
UPDATE message SET message_name = '瓜瓜不见了' WHERE message_id = 40
> Affected rows: 0
> 时间: 5.325s
SELECT * FROM message WHERE message_id = 40
> OK
> 时间: 0.017s
COMMIT
> OK
> 时间: 0.015s
-
结论:在修改操作是,会有阻塞现象,知道我提交了第一个事务才继续运行。
-
补充:
- 自动加锁和where或set的条件字段是否为索引和主键无关。
- 自动加的锁和手动加的FOR UPDATE锁是同一种类型的锁(排它锁)。
- 刚开始我以为自动加锁会与隔离级别有关,于是更换了READ-COMMITTED和READ-UNCOMMITTED隔离级别测试,发现事务执行update语句都会自动加锁,影响别的事务。
show variables like '%tx_isolation%';
set tx_isolation='READ-COMMITTED';
set tx_isolation='READ-UNCOMMITTED';
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgejfjj
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01