ANSI/ISO SQL的四个isolation level
SERIALIZABLE
这是最高层次isolation level,这个层次的isolation实现了串行化的效果,即:几个Transcation在执行时,其执行效果和某个串行序执行这几个Transaction的效果是一样的。使用Serializable层次的事务,其中的查询语句在每次都必须在同样的数据上执行,从而防止了phantom read,其实现机制是range lock。与下一个层次的不同之处在于range lock。
在基于锁的DBMS中,Serializable直到事务结束才释放select数据集上的读、写锁。而且select查询语句必须首先获得range-locks才能执行。在非锁并行的DBMS中,系统每当检测到write collision时,一次只有一个write能被写入。
range lock
Range lock记录Serializable Transaction所读取的key值范围,阻止其他在这个key值范围内的记录被插入到表中。Range lock位于Index上,记录一个起始Index和一个终止Index。在Range lock锁定的Index范围内,任何Update、Insert和Delete操作都是被禁止的,从而保证了Serializable中的操作每次都在同样的数据集上进行。
REPEATABLE READS
在基于锁的DBMS中,Repeatable Reads直到事务结束才释放select数据集上的读、写锁。但不会使用range lock,因此会产生Phantom Read。
READ COMMITTED
在基于锁的DBMS中,Read Committed直到事务结束才释放select数据集上的写锁,但读锁会在一个select完成后才被释放。和Repeatable Read一样,Read Committed不使用range lock,会产生Phantom read和Unrepeatable read。(注:这段主要参考wikipedia,我也搜索过Read Committed,基本都采用了这种说法。但我有一个疑问,既然write锁直到事务提交才释放,那么在这个阶段是不会发生update操作的,在一个事务中的多个读应该也不会产生不同的结果才对。望知之者指点一二,小弟不胜感激。)
READ UNCOMMITTED
这是Isolation Level的最底层,不仅会产生Phantom Read、Unrepeatable Read,还会有Dirty Read的风险。
Read phenomena
SQL 92标准将事务T1读写T2的操作分为三种,Phantom Read、Unrepeatable Read和Dirty Read
Users
id
name
age
1 |
Joe |
20 |
2 |
Jill |
25 |
Dirty reads (Uncommitted Dependency)
事务T1在读取事务T2已经修改、但T2还未提交的数据时会发生Dirty Read。这个Isolation Level唯一能保证的是Update操作按顺序执行,即事务中前面的update一定比后面的update先执行。
下面的这个例子是一个典型的Dirty Read
Transaction 1
Transaction 2
/* Query 1 */
SELECT age FROM users WHERE id = 1;
/* will read 20 */
|
|
|
/* Query 2 */
UPDATE users SET age = 21 WHERE id = 1;
/* No commit here */
|
/* Query 1 */
SELECT age FROM users WHERE id = 1;
/* will read 21 */
|
|
|
ROLLBACK; /* lock-based DIRTY READ */
|
Non-repeatable reads
在一个事务T1中,如果对同一条记录读取两次而值不一样,那么就发生了Non-repeatable read。
在基于锁的DBMS中,Non-repeatable read可能在未获得read lock时进行select操作,或在select操作刚结束就释放read lock时发生。在多版本并行控制的DBMS中,non-repeatable read可能在违背“受commit conflict影响的事务必须回滚“的原则时发生。
Transaction 1
Transaction 2
/* Query 1 */
SELECT * FROM users WHERE id = 1;
|
|
|
/* Query 2 */
UPDATE users SET age = 21 WHERE id = 1;
COMMIT; /* in multiversion concurrency
control, or lock-based READ COMMITTED */
|
/* Query 1 */
SELECT * FROM users WHERE id = 1;
COMMIT; /* lock-based REPEATABLE READ */
|
有两种方式来防止non-repeatable read。第一种方式用锁使T1和T2串行。另外一种方式是在多版本并行控制的DBMS中使用的。在这里,T2可以提交,而先于T2启动的T1则在自己的Snapshot(快照)里继续执行,在T1提交时,系统会检查其结果是否与T1、T2序执行的结果一样,如果一样,则T1提交,否则T1必须回滚并生成一个serialization failure。
Phantom reads
Phantom read是指在一个事务中,执行两个或多个同样的查询返回的结果集却不相同的现象。这种现象发生在没获得range lock即进行select... where....操作时,解决方法是使用range lock。
Transaction 1
Transaction 2
/* Query 1 */
SELECT * FROM users
WHERE age BETWEEN 10 AND 30;
|
|
|
/* Query 2 */
INSERT INTO users VALUES ( 3, 'Bob', 27 );
COMMIT;
|
/* Query 1 */
SELECT * FROM users
WHERE age BETWEEN 10 AND 30;
|
|
参考:
http://msdn.microsoft.com/en-us/library/ms191272.aspx
http://en.wikipedia.org/wiki/Isolation_%28database_systems%29
分享到:
相关推荐
RANSACTION ISOLATION LEVEL
To make use of either more or less strict isolation levels in applications, locking can be customized for an entire session by setting the isolation level of the session with the SET TRANSACTION ...
在Oracle中,锁(Lock)和隔离级别(Isolation Level)是确保多用户环境下数据一致性和完整性的关键组成部分。本篇文章将深入探讨这两个概念及其在实际应用中的重要性。 一、Oracle锁机制 1. **锁定类型**: - **...
第一部分、SQL&PL/SQL [Q]怎么样查询特殊字符,如通配符%与_ ...[A]set transaction [isolation level] read committed; 默认语句级一致性 set transaction [isolation level] serializable; read only; 事务级一致性
public IsolationLevel IsolationLevel { get; set; } = IsolationLevel.ReadCommitted; public bool IsReadOnly { get; set; } public void ExecuteWithTransaction(Func<bool> action) { using (var ...
本文将从 MVCC 机制出发,讨论 Snapshot Read 和 Current Read 两种读取方式的区别,然后深入分析 MySQL 加锁机制的实现细节,包括 Cluster Index、2PL、Isolation Level 等方面。最后,本文还将对死锁原理和分析...
Interface and Isolation Level Translators Interface and Isolation Protection Products Power Management Linear Regulators Power Management Multi-Output Regulators Switches and Multiplexers Analog Cross...
* 执行返回 DataSet 对象的带参数的命令(事务模式):BtuDatabaseControl.DBLayerHelp.ExecuteDataSet(string, System.Data.CommandType, System.Data.Common.DbParameter[], System.Data.IsolationLevel) ...
db.IsolationLevel = IsolationLevel.ReadCommitted; }); var sessionFactory = configuration.BuildSessionFactory(); ``` SQL Server连接: 对于SQL Server,需要安装Microsoft SQL Server的ADO.NET驱动(如...
显式事务可以提供更多的控制权,例如可以指定事务的名称、 isolation level等。 6. 事务的 isolation level 事务的隔离级别(Isolation Level)决定了事务执行过程中的并发控制机制。常见的隔离级别包括Read ...
TransactionIsolationLevel = (IsolationLevel?)System.Data.IsolationLevel.ReadCommitted, QueuePollInterval = TimeSpan.FromSeconds(15), JobExpirationCheckInterval = TimeSpan.FromHours(1), ...
在MySQL中,可以通过`SET TRANSACTION ISOLATION LEVEL`语句来改变当前会话的事务隔离级别。例如,要设置为读已提交,可以执行: ```sql SET TRANSACTION ISOLATION LEVEL READ COMMITTED; ``` 而要恢复到默认的可...
mysql> set global transaction isolation level read committed; Query OK, 0 rows affected (0.00 sec) mysql> set session transaction isolation level read committed; Query OK, 0 rows affected (0.00 sec) ...
SET TRANSACTION [ISOLATION LEVEL level] [READ ONLY | READ WRITE]; ``` - **示例**: - 设置事务为只读: ```sql SQL> set transaction readonly; ``` - 设置事务为读写,默认情况: ```sql SQL> set ...
总之,MySQL 的事务隔离机制允许用户根据需要选择合适级别的隔离,同时提供了 `SET TRANSACTION ISOLATION LEVEL` 命令和 Spring 的 `@Transactional` 注解来灵活配置,以保证数据的一致性和应用的性能。对于开发者...
│ Level.java │ Logging.java │ LoggingMXBean.java │ LoggingPermission.java │ LogManager.java │ LogRecord.java │ LogUtil.java │ LogUtil2.java │ MemoryHandler.java │ PropertiesFactory.java │ ...
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED 说明:如果指定GLOBAL,那么定义的隔离级将适用于所有的SQL用户;如果指定SESSION,则...
在Oracle中,可以使用`SET TRANSACTION ISOLATION LEVEL`语句来显式地设置事务的隔离级别。例如: ```sql SET TRANSACTION ISOLATION LEVEL READ COMMITTED; ``` 或者在会话级别设置: ```sql ALTER SESSION SET ...