6

我想在我的项目中使用TransactionScope。我阅读了它,发现它在数据库中创建了一个隐式事务。我想知道TransactionScope是否锁定它操纵的表格?TransactionScope锁定表和IsolationLevel

例如在此代码:

using (Entities ent = new Entities()) 
{ 
    using (TransactionScope tran = Common.GetTransactionScope()) 
    { 
     var oldRecords = ent.tblUser.Where(o => o.UserID == UserID); 

     foreach (var item in oldRecords) 
     { 
      ent.tblUser.DeleteObject(item); 
     } 

public static TransactionScope GetTransactionScope() 
{ 
    TransactionOptions transactionOptions = new TransactionOptions(); 
    transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.Serializable; 
    return new TransactionScope(TransactionScopeOption.Required, transactionOptions); 
} 

被锁定tblUser直到Complete命令问题?

是否IsolationLevel在显式事务中类似于隐式事务?

感谢

回答

9

这是的SQL Server,做锁定 - 如果需要的话。 任何UPDATEDELETE操作必须得到一个独占锁它影响的那些行 - 如果这些已被另一个事务锁定,它不能这样做。

所以在你的情况下,如果你从数据库中删除了一些行,默认情况下SQL Server会锁定那些行只有 - 那些被删除的行。它不会锁定整个表格。这是除非一次删除了很多行 - 如果在单个事务中删除多于5'000行,SQL Server将尝试执行锁升级并锁定整个表(而不是保持和管理5000多个单独的行锁)。

隔离级别只定义了多久阅读将锁定一个行 - 行会默认(READ COMMITTED),有共享只为它的读取时间锁定 - 通常是一个非常非常短的时间。在隔离级别为REPEATABLE READ时,共享锁将一直保留到当前事务结束,并且SERIALIZABLE将不仅锁定正在读取的行,而且锁定整行范围。但又说:那只有影响阅读操作 - 这对DELETEUPDATE声明没有直接的影响(不必行上的共享锁可以防止DELETE从获取它的其他的排他锁,它需要)

+0

很好的答案。 @marc_s在上面的代码中,如果我删除了'ID = 1'的记录,那时候另一个线程想要读'ID = 1'发生了什么?你说我应该得到排他锁,但'TransactionScope'得到隐式锁? – Arian

+0

如果您的DELETE事务获得排他锁,则其他事务不能读取此行 - 它将被锁定,并且可能会超时 –