在事务范围内部或外部分配属性



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

a是使用 Linq-to-SQL 从数据库具体化的对象。其所有属性Auto-Sync设置为 AlwaysGetXxxxx()是对 Web 服务的 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会阻止整个网站?所以正确的一个是第二?

System.Transactions.Transaction

它处于活动状态时进行的第一个数据库调用时开始。这意味着,假设您移动的两行不调用数据库,则两个变体都执行相同的操作。

这使得这成为一个风格问题。选择使您的意图最清晰的内容。

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

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

但是,如果您担心阻塞整个数据库,则可以更改 隔离级别 TransactionScope 。默认隔离级别为 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();
}

最新更新