在 TransactionScope 内部或外部分配属性?

Assign properties inside or outside of TransactionScope?

我正在使用 SQL Server 2008 和 Linq-to-SQL。

a 是使用 Linq-to-SQL 从数据库具体化的对象。它的所有属性都已将 Auto-Sync 设置为 AlwaysGetXxxxx() 是对 Webservice 的 HTTP 请求。它不包含任何嵌套事务。通常不会超过几秒钟,但有时可能需要长达 3-4-5-10 分钟。

所以...更喜欢哪一个?

using (var t = new TransactionScope())
{
    a.Xxxxx = GetXxxxx();
    a.UpdatedOn = DateTime.UtcNow;
    database.SubmitChanges();
    a.Signature = CalculateSignature(a);
    database.SubmitChanges();
    t.Complete();
}

或者:

a.Xxxxx = GetXxxxx();
a.UpdatedOn = DateTime.UtcNow;
using (var t = new TransactionScope())
{
    database.SubmitChanges();
    a.Signature = CalculateSignature(a);
    database.SubmitChanges();
    t.Complete();
}

第一个变体看起来更清晰。但是,如果 GetXxxxx() 需要 3-4-5-10 分钟怎么办? TransactionScope 在这种情况下会阻止整个网站吗?那么正确的是第 2 个?

Denise Skidmore 谈到使用 2ed 方法时可能遇到的 UpdatedOn 字段问题。

但如果您担心阻塞整个数据库,您可以更改 TransactionScopeIsolationLevel。默认隔离级别为 Serializable

Volatile data can be read but not modified, and no new data can be added during the transaction.

所以为了避免阻塞你可以把它改成ReadCommitted

Volatile data cannot be read during the transaction, but can be modified.

甚至 ReadUncommitted

Volatile data can be read and modified during the transaction.

你可以这样做:

var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
using (var t = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
{
    a.Xxxxx = GetXxxxx();
    a.UpdatedOn = DateTime.UtcNow;
    database.SubmitChanges();
    a.Signature = CalculateSignature(a);
    database.SubmitChanges();
    t.Complete();
}

A System.Transactions.Transaction 在其处于活动状态时进行的第一个数据库调用开始。这意味着假设您移动的两行不调用数据库,这两种变体都会执行相同的操作。

这就是风格问题。选择让您的意图最明确的内容。

可序列化隔离不会阻塞整个数据库。我认为这超出了问题的范围,但您可以在网上轻松找到相关信息。