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

时间:2015-01-06 22:54:33

标签: c# asp.net sql-server-2008 linq-to-sql 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 个答案:

答案 0 :(得分:1)

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

但如果您担心阻止整个数据库,则可以更改TransactionScope的{​​{3}}。默认隔离级别为Serializable

  

可以读取易失性数据但不能修改,也不能有新数据   在交易期间添加。

为避免阻止,您可以将其更改为ReadCommitted

  

在交易过程中无法读取易失性数据,但可以   修改。

甚至是ReadUncommitted

  

在交易过程中可以读取和修改易失性数据。

你可以这样做:

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();
}

答案 1 :(得分:1)

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

这使得这成为一种风格问题。选择什么使你的意图最清楚。

Serializable isolation不会阻止整个数据库。我认为这超出了问题的范围,但您可以在网上轻松找到有关此内容的信息。