数据库事务的隔离级别:
一、根源——事务并发带来的问题。
二、在数据库事务的隔离级别(五个隔离级别)不同时,数据库中的数据可能会出现以下几种情况:(顺序是对应的隔离级别从低到高)
1、None 不使用事务(一般可省略)
2、Read uncommitted 读未提交(一个事务可以读取另一个未提交事务的数据)
可能出现的问题:脏读、不可重复读、幻读
——当一个事务正在进行时,更改了数据库的数据,但还未提交。另一个事务就读取了数据库中那个事务刚刚修改过的数据,这就是脏读。
3、 Read committed 读提交(一个事务要等另一个事务提交后才能读取数据)
可能出现的问题:不可重复读、幻读
——在一个事务中,前后两次对数据库中同一个数据进行读取,但是读取的结果前后不同。这是因为在这个事务执行的时候,另一个事务恰好修改了这块数据。
4、Repeatable read 重复读 (在开始读取数据(事务开启)时,不允许修改的操作)
可能出现的问题:幻读(对应insert操作)
——当一个事务,批量修改数据库中记录的某些或者某个列的数据时,比如把visibility从0修改到了1,但是在正在执行,还未提交之前。有另一个事务插入了一条数据,其中的visibility值为0,且进行了提交。当那个事务提交之后,发现数据库中为什么还会存在一条visibility值为0的数据,难道是我没有修改他么???这就出现了幻觉,也就是所谓的幻读。
5、Serializable 串行化
不会出现前面三种问题
——好处:在该级别下,事务串行化顺序执行,避免前三种问题;
缺点:效率低下,比较消耗数据库性能,是以“锁表”这种粗暴的方法避免的。(一般情况下不使用)
三、MySQL默认的事务隔离级别是:Repeatable read 重复读;
Sql Server,Oracle默认的事务隔离级别是:Read committed 读提交。
四、三种问题的比较:
脏读是事务未提交状态下的问题。
不可重复读和幻读都是事务提交状态下的问题。
区别是——不可重复读考虑的是同一块数据,而幻读是一批数据。
五、注意:
Oracle是在串行化隔离级别上,杜绝幻读的存在。
InnoDB是在重复读的隔离级别上,杜绝幻读的存在,原因在于使用了Next-key Locking锁,锁住了Gap。
以上四种隔离级别依次上升,安全性也依次上升。但是系统的并发性能却依次下降!
六、设置隔离级别
1、设置全局的隔离级别
set global transaction isolation level [四种隔离级别]
2、设置会话隔离级别
set session transcation isolation level [四种隔离级别]