我正在使用SQL Server 2008和Linq-to-SQL。
a
是使用Linq-to-SQL从数据库实现的对象。其所有属性的Auto-Sync
都设置为Always
。 GetXxxxx()
是对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
会阻止整个网站吗?那么正确的是第二个吗?
答案 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不会阻止整个数据库。我认为这超出了问题的范围,但您可以在网上轻松找到有关此内容的信息。