一、事务并发带来的问题
1.1 第一类丢失更新
两个事务同时更新一行数据,第一个事务正常更新,第二个事务中途退出回滚数据到初始状态,导致第一个事务更新失效。
如:银行卡存储了用户甲的余额4000,此时事务A和B同时开始更新余额,事务A将余额更新到5000后正常退出,事务B执行出错导致更新失败,然后回滚余额到开始的状态4000。于是就产生了第一类丢失更新
1.2 第二类丢失更新
和上面第一类丢失更相反,第二类丢失更新的意思是事务B更新了数据,但是事务A退出导致数据回滚,事务B更新失效。
1.3 脏读
事务A更改了数据未提交,事务B读取数据,然后事务A回滚,此时事务B进行了一次脏读。
如:
小张银行卡余额为5000元,这天财务处发了4000工资,小张一看余额有9000元,非常高兴的把卡给了老婆并说这卡里有9000块。但是这时财务处发现工资发错人了,先扣回了4000工资。这个过程中小张就于执行了一次脏读,随之而来的就是老婆的一顿暴打。。。
1.4 不可重复读
一个事务,多次读同一个数据。在这期间另外一个事务对数据进行了修改并提交,导致事务前后读数据不一致。
例如:事务A给读取用户工资为5000,事务B修改工资为8000并提交,此时事务A再次读工资发现工作变成了8000,两次读取数据不一致,导致不可重复读。
1.5 幻读
事务A执行了一个包含多行数据的查询,例如计算符合条件的记录数量,事务B添加或者删除一行并提交,事务A再次读取记录数量就发生了变化,造成幻读。
例如:事务A查询工资高于8000的员工数量有10个,事务B添加了一个新纪录工资为9000并提交。此时事务A再次查询工资高于8000的员工数量为11,比之前多出一行记录,产生幻读。
二、事务的隔离级别
1. READ_UNCOMMITTED
事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。
解决第一类丢失更新的问题,但是会出现脏读、不可重复读、第二类丢失更新的问题,幻读。
2. READ_COMMITTED
保证一个事务修改的数据提交后才能被另外一个事务读取,即另外一个事务不能读取该事务未提交的数据,oracle
默认隔离级别。
解决第一类丢失更新和脏读的问题,但会出现不可重复读、第二类丢失更新的问题,幻读问题。
3. REPEATABLE_READ
保证一个事务相同条件下前后两次获取的数据是一致的,mysql
默认隔离级别 。
解决第一类丢失更新,脏读、不可重复读、第二类丢失更新的问题,但会出幻读。
4. SERIALIZABLE
事务被处理为顺序执行,一次只会执行一个事务。
解决所有问题,效率低。
5. 汇总
隔离级别 | 第一类丢失更新 | 第二类丢失更新 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|---|---|
READ_UNCOMMITTED | √ | × | × | × | × |
READ_COMMITTED | √ | × | √ | × | × |
REPEATABLE_READ | √ | √ | √ | √ | × |
SERIALIZABLE | √ | √ | √ | √ | √ |
三、查看和修改隔离级别
3.1 查看当前隔离级别
1 |
SELECT @@tx_isolation |
MySQL的默认隔离级别是PEPEATABLE_READ
:
3.2 设置隔离级别
1 |
set session transaction isolation level 隔离级别 |
评论