数据库的事务隔离级别分析
2009-04-10 16:40
141 查看
在数据库系统中,隔离
是定义一个操作对数据所做的改变如何/何时对其它的并行
操作可见。
隔离级别
数据库系统有四个隔离级别。对数据库使用何种隔离级别要审慎分析,因为
1. 维护一个最高的隔离级别虽然会防止数据的出错,但是却导致了并行度的损失,以及导致死锁出现的可能性增加。
2. 然而,降低隔离级别,却会引起一些难以发现的bug。
在不同的并行控制模式下,对各隔离级别的实现是不同的。
SERIALIZABLE(序列化)
所有的数据库事务都完全隔离,就如系统中所有的事务都顺序执行一样,一个接着一个。当然,数据库可以同时执行多个事务,只要顺序执行的“错觉”可以维护(即同时执行的多个事务不会互相干扰,或者多个事务的同时执行能保证结果的正确)。
a. 基于锁的并行控制。(当执行一个带有范围的where子句的查询时,需要范围锁定)
b. 无锁并行控制。不需要锁,但是当系统检测到并行的事务违反了序列化“错觉”,它会迫使那个事务回退,所以应用程序需要重新启动那个事务。
幻读,脏读,不可重复读等问题都不会发生。
REPEATABLE READ(可重复读)
所有查询到的数据记录都不会被改变。即会在所有获取的数据上加上读锁,但是不会加上范围锁。
可能发生的问题:当执行一个范围查询时,可能会发生幻读。
READ COMMITTED(提交读)
一个查询所获取的数据可以被其他事务修改。
读锁:在所读取的数据上添加读锁,但会立即释放。
写锁:不会释放,直到事务完结。
可能发生的问题:不可重复读。
READ UNCOMMITTED(未提交读)
一个事务可以看见另一个事务所做的未提交修改。
可能发生的问题:脏读。
总结:
可以看到,对于前三种隔离级别,其实他们的不同是通过对获取的数据实行不同类型的共享机制来实现,比如添加范围锁、读锁或者立即释放读锁等来实现,但跟排他锁无关。
隔离级别 | 添加的共享锁 |
序列化 | 范围锁 |
可重复读 | 读锁 |
提交读 | 立即释放读锁 |
而对于第四种隔离级别:未提交读,一个事务可以看到另一个事务未提交的数据。
问题
我们看到,当执行不同的隔离级别时,可能会发生各种各样不同的问题。下面对它们进行总结并举例说明。
幻读
幻读发生在当两个完全相同的查询执行时,第二次查询所返回的结果集跟第一个查询不相同。
发生的情况:没有范围锁。
例子:
事务1 | 事务2 |
SELECT * FROM users WHERE age BETWEEN 10 AND 30 ; | |
INSERT INTO users VALUES ( 3 , 'Bob' , 27 ) ; | |
SELECT * FROM users WHERE age BETWEEN 10 AND 30 ; |
如何避免:实行序列化隔离模式,在任何一个低级别的隔离中都可能会发生。
不可重复读
在多版本并行控制机制中,当一个遇到提交冲突的事务需要回退但却被释放时,会发生不可重复读问题。
事务1 | 事务2 |
SELECT * FROM users WHERE id = 1 ; | |
UPDATE users SET age = 21 WHERE id = 1 ; COMMIT; /* in multiversion concurrency*/ control, or lock-based READ COMMITTED * | |
SELECT * FROM users WHERE id = 1 ; | |
COMMIT; /* lock-based REPEATABLE READ */ |
在上面这个例子中,事务2提交成功,它所做的修改已经可见。然而,事务1已经读取了一个其它的值。在序列化和可重复读的隔离级别中,数据库管理系统会返回旧值,即在被事务2修改之前的值。在提交读和未提交读隔离级别下,可能会返回被更新的值,这就是“不可重复读”。
有两个策略可以防止这个问题的发生:
1. 推迟事务2的执行,直至事务1提交或者回退。这种策略在使用锁时应用。
2. 而在多版本并行控制中,事务2可以被先提交。而事务1,继续执行在旧版本的数据上。当事务1终于尝试提交时,数据库会检验它的结果是否和事务1、事务2顺序执行时一样。如果是,则事务1提交成功。如果不是,事务1会被回退。
脏读
事务1 | 事务2 |
SELECT * FROM users WHERE id = 1 ; | |
UPDATE users SET age = 21 WHERE id = 1 | |
SELECT FROM users WHERE id = 1 ; | |
COMMIT; /* lock-based DIRTY READ */ |
相关文章推荐
- 深入分析MSSQL数据库中事务隔离级别和锁机制
- 深入分析MSSQL数据库中事务隔离级别和锁机制
- SqlAlchemy 中操作数据库时session和scoped_session的区别(源码分析)
- 数据库分析的简单步骤
- 数据库的事务隔离级别的基础知识
- leetcode 181 Employees Earning More Than Their Managers 不会分析的数据库复杂度
- struts2.X心得4--struts2与hibernate连接数据库案例分析
- 数据库连接失败的原因分析及解决办法
- oracle数据库之性能问题分析,相关数据字典
- ORACLE 快速批量导入文本数据到数据库(sqlldr工具)方法与分析
- 设计模式综合实例分析之数据库同步系统
- 数据库 ACCESS与SQL SERVER 2000分页SQL语句 分析
- SugarCRM源码分析之数据库连接
- TrueLove 项目感悟(一)功能分析、数据库设计
- 关于打开数据库时提示"对象打开时,不允许操作",问题分析及解决办法
- 讲解MSSQL数据库中SQL锁机制和事务隔离级别
- 通过vmstat的简单分析数据库操作
- 【数据库事务日志碎片原理分析与方案】-分析篇
- Android数据库ORM框架用法、源码和性能比较分析
- Android数据库接口性能分析