比如 一张表a 有 user_code,shared,del,company_id四个字段 我想查shared=1 且 del=0 或者del=0的数据 且company_id=1, shared是共享的意思,不区分公司,那么可以这样写
例 select user_code from a where shared=1 and del=0 or del=0
众所周知,Mysql在InnoDB下有四种隔离级别:
未提交读(Read Uncommitted)
提交后读(Read Committed)
可重复读(Repeatable Read)
串行化(Serializable)
其中可重复读(RR)可以避免脏读( a事务读到b事务回滚前的数据)以及可不重复读( a事务在b事务修改提交的前后,两次分别读到的数据不一致)。但是对于幻读(a事务在b事务insert提交前后,两次分别读到的数据不一致),却存在争议。
下面我们来做一个试验:
对于下面这张简单的数据表
id num
1 11
2 22
3 33
我们开启a、b两个事务
a事务 b事务
begin begin
select * from tb ----
---- insert into tb (id,num)values(4,44)
---- commit
select * from tb ----
commit
试验结果:a事务的两次select查询到的结果相同,在后一次查询中没有返回新插入id=4的那条记录。
据此,很多人判断说RR隔离级别下“不存在”幻读。
但果真如此吗?----
出现上面的试验结果,是因为在RR隔离级别事务下,Mysql会对前一次select的结果快照。所以第二次select其实是快照读(这也正是RR隔离级别下能够避免不可重复读的策略)。
如果我们把试验条件稍作修改,同样开启a、b两个事务:
a事务 b事务
begin begin
select * from tb ----
---- insert into tb (id,num)values(5,55)
---- commit
update tb set num=num+1 ---- #此处a事务做一次修改 *** 作
select * from tb ----
commit
试验结果:在a事务的第二次select中出现了b事务新插入的id=5的记录。
由于做了update *** 作,之前的快照失效了,所以说RR隔离级别下的快照策略并没能真正避免幻读。
ps. 假如给第二次的select查询上锁(无论是共享锁还是排它锁),也会得到同样的结果,都会令快照失效。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)