详解让人困惑的更新锁
其它锁都好理解,唯独更新锁让人迷糊,因为它混合了锁和标记,在更新前我们首先要读取记录,在读取期间锁是共享的,而在真正更新时,我们需要独占锁,更新锁是非常短暂的。

图 9 更新时用到的几种锁
不同隔离级别之间的差异,以及何时使用它们
有4种事务隔离级别,下表列出了这4种隔离级别及其使用时间。
| 隔离级别 | 读 | 更新 | 插入 |
| 读未提交的 | 读取未提交的数据 | 允许 | 允许 |
| 读已提交的(默认) | 读取已提交的数据 | 允许 | 允许 |
| 重复读 | 读取已提交的数据 | 不允许 | 允许 |
| 序列化 | 读取已提交的数据 | 不允许 | 不允许 |
如何指定隔离级别?
隔离级别是关系数据库的一个功能,也就是说,它基本上只与SQL Server相关,而与ADO.NET,EF或LINQ是没有什么关系的,但你可以在这些组件上设置隔离级别。

图 10 隔离级别
中间层:在中间层,你可以使用事务范围对象指定隔离级别。
TransactionOptions TransOpt = New TransactionOptions();
TransOpt.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
using(TransactionScope scope = new
TransactionScope(TransactionScopeOption.Required, TransOptions))
{
TransOpt.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
using(TransactionScope scope = new
TransactionScope(TransactionScopeOption.Required, TransOptions))
{
ADO.NET:在ADO.NET中你可以使用SqlTransaction对象指定事务隔离级别。
SqlTransaction objtransaction =
objConnection.BeginTransaction(System.Data.IsolationLevel.Serializable);
objConnection.BeginTransaction(System.Data.IsolationLevel.Serializable);
SQL Server:你也可以在TSQL中使用“SET TRANSACATION ISOLATION LEVEL”指定隔离级别。
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
事务隔离级别与它能解决的并发性问题之间的对应关系
| 读已提交的 | 重复读 | 序列化 | 读未提交的 | |
| 脏读取 | 能解决 | 能解决 | 能解决 | 不能 |
| 丢失更新 | 不能 | 能解决 | 能解决 | 不能 |
| 非重复读 | 不能 | 能解决 | 能解决 | 不能 |
| 幻想行 | 不能 | 不能 | 能解决 | 不能 |