一、事务隔离级别
先来看张图,通过这张图可以加深记忆。
隔离级别就是为了解决脏读、不可重复读、幻读的问题,所以首先来理解一下这三个概念。并能结合字面意思进行记忆。
脏读:顾名思义,指的是读到的数据是脏数据。或者称为中间数据。
例: 初使X=0 A1把X设置为1,A2读取时X是1,但A1后面又修改成了2,或回滚到了0,然后提交事务。那么A2读取的数据就是脏数据。A2读取的是未提交的数据。
不可重复读:顾名思义,指的是一个事务中的两次读取的数据不一致,可能是因为中间有别一个事务进行update。
例:初使X=0 A1事务第一次读到X=0,1秒后事务还没结束,又读到X=1。因为在这1秒中另一个事务A2完成了update X=1的操作。
幻读:顾名思义,指的是像发生了幻觉一样的事情。指的是一个事务处理的规定的数据,这时另一个事务又新增了记录。结果就是事务A认为明明处理完成了,为什么还有没处理的记录。
例如:A1事务把所有X=0 的记录都update 成X=1 。这时事务A2又新增了3条X=0的记录。对于A1来说,这3条记录就像是幻觉一样。因为他刚处理完,又出现了。
4种隔离级别,针对脏读、不可重复读、幻读的问题,进行解决。
读未提交:顾名思义,指的是所有事务都可以看到其他未提交事务的执行结果。,即脏数据。没有任何事务控制。读到的数据可能是中间数据。一般生产数据库不会设为读未提交。
读已提交:顾名思义,指的是读到的数据都是commit后的数据。此时数据库是有事务控制。读已提交解决了脏读的问题。
可重复读:顾名思义,指的是在同一个事务中可以重复读相同的记录。因为数据库会当前事务限制读取到其它事务update后的数据。解决了不可重复读的问题。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。因为它只是不允许读到update的记录,却允许insert新的记录。
可串行化:顾名思义,是所有的select、insert、update、delete等操作都是排队一个一个串行的执行。每一次执行都会对表进行加锁。所以可以解决幻读的问题。
二、解决脏读、不可重复读、幻读的方法:
解决脏读:事务,只有commit后的记录才可以看得到。只有commit的记录才是最终保存到数据库。
解决不可重复读:类似版本号控制,每次事务读到的是同一个事务提交的版本。
解决幻读:表级锁
三、数据库默认隔离级别:
oracle等大多数据库:读提交。解决最常见的脏读问题。
mysql:可重复读。
四、通过行锁解决部分表幻读问题:
1、新建一个LOCK表,新增记录来表示锁的类型。如用户、订单。
2、当A1事务对用户查询或修改时,对LOCK表的用户进行加锁,此时其它线程A2无法获取锁,所以无法操作。用数据库的
select xx from table where yy=zz for update...进行加锁。
3、不需要加锁的用户查询也可以不加锁的方式实现。
自己定义锁的方式,对事务的控制更加灵活、有效率。
参考:http://xm-king.iteye.com/blog/770721
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/11627468/viewspace-1793036/
,如需转载,请注明出处,否则将追究法律责任。