理解数据库事务隔离级别以及脏读, 不可重复读, 幻读
2017-03-25 15:57
543 查看
数据库事务的4个特性:
原子性(atomic): 都成功或者都失败;
一致性(consistency):事务操作之后,数据库所处的状态和业务规则是一致的;比如a,b账户相互转账之后,总金额不变;
隔离性(isolation):操作中的事务不相互影响;
持久性(durability):事务提交后被持久化到数据库.
脏读,不可重复读, 幻读
[b]脏读dirty read:[/b]事务1更新了记录,但没有提交,事务2读取了更新后的行,然后事务T1回滚,现在T2读取无效。
[b]不可重复读unrepeatable read:[/b]事务1读取记录时,事务2更新了记录并提交,事务1再次读取时可以看到事务2修改后的记录;
幻读phantom read:事务1读取记录时事务2增加了记录并提交,事务1再次读取时可以看到事务2新增的记录;
事务隔离级别描述:
脏读 不可重复读
幻读
READ UNCOMMITTED: 允许 允许 允许
READ COMMITTED: 不允许 允许 允许
REPEATABLE READ: 不允许
不允许 允许
SERIALIZABLE: 不允许 不允许 不允许
Oracle默认的是 READ COMMITTED。
如何感性理解这些“深奥”的术语?个人认为, 作为一个Java程序员,这些字眼比较唬人。
首先, 隔离级别描述了事务被隔离的程度。可以简单的想象一下, 一个人因为某种原因(比如国家安全)需要被隔离,则涉及安全的机密程度越高, 需要隔离级别就越高,他与外界的沟通渠道就越少。
对于数据库而言, 每个事务都要占用一些资源,比如对表/数据享有的操作权限,事务的隔离级别描述了事务对资源享用的程度。
如果数据库的隔离级别为REAE_UNCOMMITTED, 则其他线程可以看到未提交的数据, 因此就出现脏读;
如果数据库隔离级别设为READ_COMMITTED,即没提交的数据别人是看不见的,就避免了脏读;但是,正在读取的数据只获得了读取锁,读完之后就解锁,不管当前事务有没有结束,这样就容许其他事务修改本事务正在读取的数据。导致不可重复读。
REPEATABLE READ因为对正在操作的数据加锁,并且只有等到事务结束才放开锁, 则可以避免不可重复读;
REPEATABLE READ只能保证正在被本事务操作的数据不被其他事务修改,却无法保证有其他事务提交新的数据。 则有可能线程1在操作表T1的时候(特别是统计性的事务),其他线程仍然可以提交新数据到表T1,这样会导致线程1两次统计的结果不一致,就像发生幻觉一样。
SERIALIZABLE因为获得范围锁,且事务是一个接着一个串行执行,则保证了不会发生幻读。
由此可见,隔离级别越高,受其他事物干扰越少,并发性能越差。
设置语法
Oracle:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|READ COMMITTED|READ UNCOMMITTED|REPEATABLE READ;
原子性(atomic): 都成功或者都失败;
一致性(consistency):事务操作之后,数据库所处的状态和业务规则是一致的;比如a,b账户相互转账之后,总金额不变;
隔离性(isolation):操作中的事务不相互影响;
持久性(durability):事务提交后被持久化到数据库.
脏读,不可重复读, 幻读
[b]脏读dirty read:[/b]事务1更新了记录,但没有提交,事务2读取了更新后的行,然后事务T1回滚,现在T2读取无效。
[b]不可重复读unrepeatable read:[/b]事务1读取记录时,事务2更新了记录并提交,事务1再次读取时可以看到事务2修改后的记录;
幻读phantom read:事务1读取记录时事务2增加了记录并提交,事务1再次读取时可以看到事务2新增的记录;
事务隔离级别描述:
脏读 不可重复读
幻读
READ UNCOMMITTED: 允许 允许 允许
READ COMMITTED: 不允许 允许 允许
REPEATABLE READ: 不允许
不允许 允许
SERIALIZABLE: 不允许 不允许 不允许
Oracle默认的是 READ COMMITTED。
如何感性理解这些“深奥”的术语?个人认为, 作为一个Java程序员,这些字眼比较唬人。
首先, 隔离级别描述了事务被隔离的程度。可以简单的想象一下, 一个人因为某种原因(比如国家安全)需要被隔离,则涉及安全的机密程度越高, 需要隔离级别就越高,他与外界的沟通渠道就越少。
对于数据库而言, 每个事务都要占用一些资源,比如对表/数据享有的操作权限,事务的隔离级别描述了事务对资源享用的程度。
如果数据库的隔离级别为REAE_UNCOMMITTED, 则其他线程可以看到未提交的数据, 因此就出现脏读;
如果数据库隔离级别设为READ_COMMITTED,即没提交的数据别人是看不见的,就避免了脏读;但是,正在读取的数据只获得了读取锁,读完之后就解锁,不管当前事务有没有结束,这样就容许其他事务修改本事务正在读取的数据。导致不可重复读。
REPEATABLE READ因为对正在操作的数据加锁,并且只有等到事务结束才放开锁, 则可以避免不可重复读;
REPEATABLE READ只能保证正在被本事务操作的数据不被其他事务修改,却无法保证有其他事务提交新的数据。 则有可能线程1在操作表T1的时候(特别是统计性的事务),其他线程仍然可以提交新数据到表T1,这样会导致线程1两次统计的结果不一致,就像发生幻觉一样。
SERIALIZABLE因为获得范围锁,且事务是一个接着一个串行执行,则保证了不会发生幻读。
由此可见,隔离级别越高,受其他事物干扰越少,并发性能越差。
设置语法
Oracle:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE|READ COMMITTED|READ UNCOMMITTED|REPEATABLE READ;
相关文章推荐
- 理解数据库事务隔离级别以及脏读, 不可重复读, 幻读
- 理解数据库事务隔离级别以及脏读, 不可重复读, 幻读
- 理解数据库事务隔离级别以及脏读, 不可重复读, 幻读
- 理解数据库事务隔离级别以及脏读, 不可重复读, 幻读
- 数据库事务隔离级别,以及脏读,幻读,不可重复读!
- 数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
- 数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
- 数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
- 数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
- 数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
- 脏读、不可重复读、幻读以及事务的五种隔离级别
- 数据库事务隔离级别--脏读,幻读,不可重复读
- 数据库事务隔离级别-- 脏读、幻读、不可重复读
- 数据库事务中的脏读,不可重复读与幻读及数据库的隔离级别
- 数据库事务隔离级别-- 脏读、幻读、不可重复读
- 数据库的事务、脏读、不可重复读和幻读 以及隔离机制
- 数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
- 数据库事务隔离级别-- 脏读、幻读、不可重复读(清晰解释)
- 数据库事务中的脏读,不可重复读与幻读及数据库的隔离级别
- 数据库事务隔离级别-- 脏读、幻读、不可重复读