吉安市规划建设局网站,找郴州一家做网站的公司电话,息壤服务器网站打不开,湖北网站推广服务疑问#xff1a;Mysql多事务默认情况下#xff0c;同时修改同一条记录运行修改吗#xff1f;是否要手动加上for update行锁。 猜想#xff1a;MySQL 会自动对涉及的数据行加上写锁#xff08;排他锁#xff09;#xff0c;以确保数据的一致性和隔离性。这是在默认的事务… 疑问Mysql多事务默认情况下同时修改同一条记录运行修改吗是否要手动加上for update行锁。 猜想MySQL 会自动对涉及的数据行加上写锁排他锁以确保数据的一致性和隔离性。这是在默认的事务隔离级别 Repeatable Read 下的行为。 验证
第一个事务不结束并对message_id40的记录进行修改
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 40Affected 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;BEGINOK时间: 0.016sSELECT * FROM message WHERE message_id 40OK时间: 0.02sUPDATE message SET message_name 瓜瓜不见了 WHERE message_id 40Affected rows: 0时间: 0.016sSELECT * FROM message WHERE message_id 40OK时间: 0.018sCOMMITOK时间: 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;BEGINOK时间: 0.015sSELECT * FROM message WHERE message_id 40OK时间: 0.016sUPDATE message SET message_name 瓜瓜不见了 WHERE message_id 40Affected rows: 0时间: 5.325sSELECT * FROM message WHERE message_id 40OK时间: 0.017sCOMMITOK时间: 0.015s结论在修改操作是会有阻塞现象知道我提交了第一个事务才继续运行。 补充 自动加锁和where或set的条件字段是否为索引和主键无关。自动加的锁和手动加的FOR UPDATE锁是同一种类型的锁排它锁。刚开始我以为自动加锁会与隔离级别有关于是更换了READ-COMMITTED和READ-UNCOMMITTED隔离级别测试发现事务执行update语句都会自动加锁影响别的事务。
show variables like %tx_isolation%;
set tx_isolationREAD-COMMITTED;
set tx_isolationREAD-UNCOMMITTED;