脏读
在一次事务中,读取了另一个尚未提交事务正在修改的数据
原因:该数据正在被另外的事务修改,数据的最终结果不能确定,就读取了数据。争夺了已经被其他事务占用的某行资源
解决:对数据加锁,不要读取正在被其他事务修改的数据。
案例:
1、mary的原工资是1000,财务人员将mary的工资改为8000,但是未提交事务
2、mary读取自己的工资,发现自己的工资为8000
3、财务发现操作事务,回滚了事务,mary的工资变成了1000.
4、但是mary读取的工资数是8000,这个数据就是脏数据。
不可重复读
在一次事务中,某一行被读取了两次,前后结果不一致的现象
原因:在事务第一次读取了数据后,有另外的事务更新了数据,某行资源被其他事务争夺。
解决:对数据加锁。事务访问数据时,需要获取数据的锁。第一个事务未提交(释放锁),不允许其他事务访问数据。
案例:
1、在事务1中,mary读取自己的工资为1000,操作并未完成。
2、在事务2中,财务人员修改了mary的工资为8000,并提交了事务。
3、在事务1中,mary再次读取自己的工资时,工资变成了8000
4、这种现象发生在一个事务中需要多次读取某行数据的情况下。
幻读
在一次事务中,对多行集合的查询被执行了两次,前后结果不一致的现象
原因:在事务第一查询后,有另外的事务修改了数据(增删改)
解决:对事务加锁或者对整个表加锁。在此种情况下,对行锁已经不起作用,第一个事务未提交,不允许其他事务执行。
案例:
1、事务1,读取所有工资为1000的员工,共10人
2、事务2,向表中插入一条员工记录,工资为1000
3、事务1,再次读取所有工资为1000的员工,共读取到的数据为11条。
4、这种想象发生在对数据库的操作设计到多行时。
/*
---------------------------------------------------------------------
事务隔离等级 | 脏读 | 不可重复读 | 幻读
-----------------+-------------+----------------------+--------------
Read Uncommitted | 可能发生 | 可能发生 | 可能发生
-----------------+-------------+----------------------+--------------
Read Committed | - | 可能发生 | 可能发生
-----------------+-------------+----------------------+--------------
Repeatable Read | - | - | 可能发生
-----------------+-------------+----------------------+--------------
Serializable | - | - | -
---------------------------------------------------------------------
*/