在mysql中写超过读
Posted
技术标签:
【中文标题】在mysql中写超过读【英文标题】:WRITE over READ in mysql 【发布时间】:2015-01-16 03:22:40 【问题描述】:我是 mysql 事务可序列化的新手。当我在其他并发会话正在读取表时尝试更新表的一行时,更新事务必须等到读取事务完成。有什么方法可以让写事务继续进行(然后读事务应该提交失败)?
这是我验证上述属性的测试:
第 1 节:
set transaction isolation level serializable;
create database locktest;
use locktest;
create table locktest(id int not null primary key auto_increment, text varchar(100));
insert into locktest(text) values('text1');
start transaction;
select * from locktest where id=1;
第 2 节:
use locktest;
update locktest set text='new_text2' where id=1; -- it gets stuck at this point and only proceed forward when I 'commit;' in session 1
我想要的是会话 2 的更新必须立即成功,会话 1 的事务应该中止。有什么建议吗?谢谢。
【问题讨论】:
【参考方案1】:在 InnoDB 实现中的 SERIALIZABLE 仅意味着 SELECT 的行为类似于 SELECT...LOCK IN SHARE MODE。
如果会话 1 不使用 START TRANSACTION,而只是依赖自动提交,那么 MySQL 的 SERIALIZABLE 概念将运行一个只读语句,如 SELECT,与 REPEATABLE-READ 完全相同。它不会锁定任何东西,也不会阻止会话 2 中的 UPDATE。
但是会话 2 中的 UPDATE 无法导致会话 1 中的 SELECT 中止。这不是 SERIALIZABLE 的行为。
另请参阅我对 MySQL - Mutual exclusion in transactions and locks? 的回答,该回答巧合地出现在今天早些时候。
您可以在此处阅读有关事务隔离模式的更多详细信息:http://dev.mysql.com/doc/refman/5.6/en/set-transaction.html
【讨论】:
所以如果我有两个读写事务:一个读取数据项 1 然后更新数据项 2,一个更新数据项 1 然后读取数据项 2,它们就没有办法发生同时。两个事务相互等待,直到超过锁等待超时,然后重试,希望事务能够获得所需数据项的所有锁并能够继续前进。对吗? 我之前与 Oracle 合作过,在这种情况下,事务返回类似于“ORA 8177。无法序列化此事务的访问”。和mysql中的'lock wait timeout exceeded'一样吗? @HieuNguyen,在您描述的场景中,如果您使用 SERIALIZABLE,第一个事务获取数据项 1 上的共享锁和数据项 2 上的排他锁。第二个事务需要一个排他锁来更新数据项 1,但是当该数据上有共享锁时,它无法获得排他锁。所以第二个事务一直等到锁等待超时。以上是关于在mysql中写超过读的主要内容,如果未能解决你的问题,请参考以下文章