事务 脏读、不可重复读、幻影读的分析
1 丢失修改
2 脏读:当事务1修改了一条记录,没有提交时,事务2读取了该记录;当事务1回滚了,那么事务2的记录就是一条不存在的记录;
3 不可重复读:当事务1读取了一条记录,未提交事务,事务2修改了该条记录并且提交事务;事务1又读取了该条记录,发现两条记录不一样;
4 幻影读:当事务1根据某种检索条件读取了若干条记录,未提交事务;而事务2又插入了一条记录,该记录也符合事务1的检索条件;那么当事务1在根据相同查询条件检索数据时候,出现了不一致的现象。
根据锁机制来避免上诉问题:
排他锁:数据加锁后,只有锁的拥有者可以对该数据进行修改和读取,其他用户不能做任何操作,也不能加锁
共享锁:数据加锁后,所有用户都可以读取该对象,但是不能修改之,其他用户也可以加共享锁
处理以上隔离级别的问题,采用如下方是:
1 处理丢失修改,采用READ_UNCOMMITTED。
2 处理脏读:采用READ_COMMITTED,修改时加排他锁,直到事务提交后才释放,读取时加共享锁,读取完释放
事务1读取数据时加上共享锁后(这样在事务1读取数据的过程中,其他事务就不会修改该数据),不允许任何事物操作该数据,只能读取,之后1如果有更新操作,那么会转换为排他锁,其他事务更无权参与进来读写,这样就防止了脏读问题。但是当事务1读取数据过程中,有可能其他事务也读取了该数据,读取完毕后共享锁释放,此时事务1修改数据,修改完毕提交事务,其他事务再次读取数据时候发现数据不一致,就会出现不可重复读问题,所以这样不能够避免不可重复读问题。
3 处理不可重复读:读采用RepeatableRead,取数据时加共享锁,写数据时加排他锁,都是事务提交才释放锁。读取时候不允许其他事物修改该数据,不管数据在事务过程中读取多少次,数据都是一致的,避免了不可重复读问题
4处理幻影读问题:用Serializable,采用的是范围锁RangeS RangeS_S模式,锁定检索范围为只读,这样就避免了幻影读问题。