mysql事务级别设置

1
2
3
4
5
6
7
8
1.查看当前数据库事务级别
SELECT @@tx_isolation
1read uncommitted : 读取尚未提交的数据 :哪个问题都不能解决
2read committed:读取已经提交的数据 :可以解决脏读 ---- oracle默认的
3)repeatable read:重读读取:可以解决脏读 和 不可重复读 ---mysql默认的
4serializable:串行化:可以解决 脏读 不可重复读 和 虚读---相当于锁表
2.设置事务隔离级别
set session transaction isolation level 【事务级别】

数据库并发会引发的问题

1.脏读(dirty read):A事务读取B事务尚未提交的更改数据,并在这个数据基础上操作。如果B事务回滚,那么A事务读到的数据根本不是合法的,称为脏读。在oracle中,由于有version控制,不会出现脏读

2.不可重复读(unrepeatable read):A事务读取了B事务已经提交的更改(或删除)数据。比如A事务第一次读取数据,然后B事务更改该数据并提交,A事务再次读取数据,两次读取的数据不一样

3.幻读(phantom read):A事务读取了B事务已经提交的新增数据。注意和不可重复读的区别,这里是新增,不可重复读是更改(或删除)。这两种情况对策是不一样的,对于不可重复读,只需要采取行级锁防止该记录数据被更改或删除,然而对于幻读必须加表级锁,防止在这个表中新增一条数据

4.第一类丢失更新:A事务撤销时,把已提交的B事务的数据覆盖掉

5.第二类丢失更新:A事务提交时,把已提交的B事务的数据覆盖掉

各类事务级别的详情

(1)读未提交:最低隔离级别,允许一个事务能够读到另一个事务未提交的信息,只对修改数据的并发操作做限制(对于数据而言,写之前加X锁,直到事务结束释放X锁,对应一级封锁协议),这样解决了第一类丢失更新的问题,虽然一个事务不能修改其他事务正在修改的数据,但是可以读到其他事务还未提交的修改,如果这些修改未提交,那么就会成为脏数据,所以还未解决脏读的问题,自然,就算是已经提交的数据,多次读取结果也不一定一样,所以还未解决不可重复读和幻读的问题(存在的问题:脏读,不可重复读,幻读)

(2)读已提交(oracle默认的):只能读取已经提交的数据,换句话说,就是一个事务读取其他事务中正在修改的数据是不被允许的(一级封锁协议+读之前加S锁,读完数据释放S锁,对应二级封锁协议),由于读完之后就释放S锁,所以不能保证不可重复读与幻读

(3)可重复读(mysql默认的):在读已提交下,同一事务内,允许多次相同的查询能够得到不同的结果,可以使用二级封锁协议+MVCC使得当前事务只能读取不高于其事务版本的数据,也可以使用三级封锁协议(一级封锁协议+读之前加S锁,直到事务结束释放S锁)能解决可重复读,同时也解决了幻读

(4)可串行化:可重复读与幻读的区别是:可重复读是更改表中行级数据,而幻读是增加表中行级数据,幻读可以通过三级封锁协议消除,可串行化使得所有的事务必须串行化执行,解决了一切并发问题,但会造成大量的等待、阻塞甚至死锁,使系统性能降低