TransactionScope锁定表和隔离级别(IsolationLevel)

8

我希望在我的项目中使用TransactionScope。我了解到它可以在数据库中创建隐式事务。我想知道这个TransactionScope是否会锁定它操作的表?

例如,在以下代码中:

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是否类似于隐式事务?

谢谢

1个回答

14

如果需要,锁定操作是由SQL Server完成的。任何UPDATEDELETE操作都必须在影响到的行上获得独占锁,如果这些行已被另一个事务锁定,则无法执行。

因此,在您的情况下,如果从数据库中删除了一些行,则SQL Server默认仅会锁定那些行-即将要删除的行。它不会锁定整个表格。这是除非您一次删除了非常大量的行-如果您在单个事务中删除了超过5,000行,则SQL Server将尝试进行锁升级并锁定整个表格(而不是维护5000+个单独的行锁)。

隔离级别仅定义了读取锁定行的时间-默认情况下(READ COMMITTED),该行仅在被读取时具有共享锁-通常是非常短暂的时间。使用隔离级别REPEATABLE READ,共享锁将一直持有到当前事务结束,SERIALIZABLE将不仅锁定正在读取的行,还会锁定整个行范围。但是再次强调:这影响读取操作-它对DELETEUPDATE语句没有直接影响(除了对行进行共享锁可能会阻止DELETE获取所需的独占锁)。


不错的回答。@marc_s在上面的代码中,如果我删除ID=1的记录,并且在那个时候另一个线程想要读取ID=1会发生什么?你说我应该获得独占锁,但是TransactionScope会获得隐式锁吗? - Arian
如果您的“DELETE”事务获得了独占锁,则其他事务无法读取此行 - 它将被锁定,并可能超时。 - marc_s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接