数据库事务隔离级别问题

查看 363|回复 30
git00ll   
我一直不理解可重读这个场景有什么存在的必要。
为什么多次查询同一条记录,想多次使用就存起来呗
leichnX
OP
  
@leichnX 你需要查询 account 和 order 两张表,查询 account 后你会获取到一个余额,然后再查询 order 时你肯定希望此时查询的明细就是查询 account 那一瞬间对应的 order ,不然如果 order 被修改了,你的 order 和 account 会对不齐。
这里的可重复读不止针对同一条数据的可重复读,如你所说业务上也许不会在事物内针对同一条数据查两遍, 但是跨表的可重复读是很有用的。
leichnX
OP
  
@watzds 这个例子很赞,确实有这么一些场景,套个可重读的隔离级别上去就可以少考虑不少事儿了,减小写代码的复杂度。
git00ll   
@git00ll 这两次查询查两张表,可重读会帮忙把它们时间间隙卡的很短吗,以前还真没了解过这个。它会和 Java 多线程一样使得两个查询之间线程不会中断吗?
leichnX
OP
  
@leichnX 不是时间间隙卡的很短。 当事物内进行第一条 sql 查询的时候就会生成一个快照版本号,并且对所有的表生效。相当于给所有的表生成了快照。 所以能够保证后续的查询(无论哪张表)都是那一瞬间的快照值,因此能够保证读一致性。
git00ll   
@git00ll 仔细想想感觉不对啊,比如手动执行 sql 的时候,先启动事务,在执行第一条查询查表 1 ,等五秒再执行第二条查询查表 2 ,这中间别人要是插了数据进表 2 去,肯定是会查出来的,什么隔离级别也会查到插进去的新数据。
leichnX
OP
  
@leichnX 针对数据插入就是 “幻读” 问题了,“可重复读” 指的是数据更新。
并且 Mysql RR 级别是能解决快照读的幻读问题的, 如你描述两次查询中间被插入符合条件的数据并不会被查出来。
leichnX
OP
  
@git00ll 又测了一下,你说的是对的,我开始拿 SERIALIZABLE 测了一遍,结果和我说的一样,我想当然的以为可重读也是会读到新插数据或改的数据。然而可重读读到的还真是旧数据,这很牛逼,很重要。
事务 A
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN
SELECT *
FROM 表 1 ;
转过去执行事务 B
SELECT *
FROM 表 2 ; //发现读到的是旧数据
commit;
事务 B
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN
UPDATE 表 2
SET Name='22'
luoqeng   
@watzds 明白了,和 20 说的是一回事,在需要获取跨表一致性数据的时候,这个可重读级别很重要。
vczyh   
没有价值的隔离级别 https://mp.weixin.qq.com/s/qnIGBq_PVh4UalOZGwwZGw
您需要登录后才可以回帖 登录 | 立即注册

返回顶部