C# LINQ to SQL 中的 TransactionScope 与事务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/542525/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:31:04  来源:igfitidea点击:

TransactionScope vs Transaction in LINQ to SQL

c#linqlinq-to-sqltransactions

提问by Ben McNiel

What are the differences between the classic transaction pattern in LINQ to SQL like:

LINQ to SQL 中的经典事务模式有什么区别,例如:

using(var context = Domain.Instance.GetContext())
{
    try
    {
        context.Connection.Open();
        context.Transaction = context.Connection.BeginTransaction();
        /*code*/
        context.Transaction.Commit();
    }
    catch
    {
        context.Transaction.Rollback();
    }         
}

vs the TransactionScope object

与 TransactionScope 对象

using (var context = Domain.Instance.GetContext())
using (var scope = new TransactionScope())
{
    try
    {
        /*code*/
        scope.Complete();
    }
    catch
    {
    }
}

采纳答案by TGnat

Linq2SQL will use an implicit transaction. If all of your updates are done within a single Submit, you may not need to handle the transaction yourself.

Linq2SQL 将使用隐式事务。如果您的所有更新都在一次提交中完成,您可能不需要自己处理事务。

From the documentation (emphasis mine):

从文档(强调我的):

When you call SubmitChanges, LINQ to SQL checks to see whether the call is in the scope of a Transaction or if the Transaction property (IDbTransaction) is set to a user-started local transaction. If it finds neither transaction, LINQ to SQL starts a local transaction (IDbTransaction) and uses it to execute the generated SQL commands.When all SQL commands have been successfully completed, LINQ to SQL commits the local transaction and returns.

当您调用 SubmitChanges 时,LINQ to SQL 会检查该调用是否在事务范围内,或者事务属性 (IDbTransaction) 是否设置为用户启动的本地事务。如果没有找到任何事务,LINQ to SQL 将启动一个本地事务 (IDbTransaction) 并使用它来执行生成的 SQL 命令。当所有 SQL 命令都成功完成后,LINQ to SQL 提交本地事务并返回。

回答by Chris Marisic

I believe they are fundamentally the same that the TransactionScope class will interface with the ADO.NET underlying connection to create and either commit or rollback the transaction. That the TransactionScope class was just created to make working with ADO.NET persistence cleaner.

我相信它们在本质上是相同的,即 TransactionScope 类将与 ADO.NET 底层连接接口以创建和提交或回滚事务。刚刚创建 TransactionScope 类是为了使使用 ADO.NET 持久性更干净。

Edit:Clarifying my statement with regards to casperOne's additionit is the TransactionScope that will create the transaction and the connection will then see the transaction that was created by the TransactionScope and use it since it's available to it.

编辑:澄清我关于casperOne 添加的声明,它是 TransactionScope 将创建事务,然后连接将看到由 TransactionScope 创建的事务并使用它,因为它对它可用。

回答by casperOne

It should be noted that when using the TransactionScopethere is no need for the try/catchconstruct you have. You simply have to call Completeon the scope in order to commit the transaction when the scope is exited.

应该注意的是,使用 时TransactionScope不需要try/catch您拥有的构造。您只需调用Complete作用域即可在退出作用域时提交事务。

That being said, TransactionScopeis usually a better choice because it allows you to nest calls to other methods that might require a transaction without you having to pass the transaction state around.

话虽如此,TransactionScope通常是更好的选择,因为它允许您嵌套调用可能需要事务的其他方法,而不必传递事务状态。

When calling BeginTransactionon the DbConnectionobject, you have to pass that transaction object around if you want to perform other operations in the same transaction, but in a different method.

当调用BeginTransaction上的DbConnection对象,你有,如果你想在同一个事务执行其他操作来传递交易对象周围,但在不同的方法。

With TransactionScope, as long as the scope exists, it will handle everything that registers with the current Transactionon the thread, making your code cleaner, and more maintainable.

使用TransactionScope,只要作用域存在,它将处理Transaction在线程上注册到当前的所有内容,使您的代码更清晰,更易于维护。

On top of that, you have the added benefit of being able to use other resources that can participate in transactions, not just the connection to the database.

最重要的是,您还可以使用其他可以参与事务的资源,而不仅仅是与数据库的连接。

It should be noted that in situations where you need to squeeze the most out of your connections and database operations, you might not want to use TransactionScope; even against a single database, you run the possibility of the Distributed Transaction Coordinator being used and having the transaction being turned into a distributed transaction (even for a single database connection).

应该注意的是,在需要最大限度地利用连接和数据库操作的情况下,您可能不想使用TransactionScope; 即使针对单个数据库,您也有可能使用分布式事务协调器并将事务转换为分布式事务(即使对于单个数据库连接)。

In these cases, while muddying up your design, you might want to consider passing a connection-specific transaction around.

在这些情况下,在混淆您的设计的同时,您可能需要考虑传递特定于连接的事务。

Or, if you know you will use one resource consistently (and on the same thread), you might want to create a class that reference-counts your connection/transaction.

或者,如果您知道您将始终如一地使用一个资源(并且在同一线程上),您可能想要创建一个引用计数您的连接/事务的类。

You would create a class that on construction, creates your resource/increments the count. It would also implement IDisposable(in which you would decrement/release/commit/abort when the count is zero), and store the count in a variable that has ThreadStaticAttributeapplied to it.

您将创建一个在构建时创建资源/增加计数的类。它还将实现IDisposable(当计数为零时,您将减少/释放/提交/中止),并将计数存储在已ThreadStaticAttribute应用于它的变量中。

This allows you to separate the transaction management from the logic code, and still hold onto a singular resource fairly efficiently (instead of escalating to a distributed transaction).

这允许您将事务管理与逻辑代码分开,并且仍然相当有效地保持单一资源(而不是升级到分布式事务)。

回答by Mayank

One big difference (lesson learnt the hard way) – TransactionScope uses MS DTC for transaction management.

一个很大的区别(艰难的教训)——TransactionScope 使用 MS DTC 进行事务管理。

If your application has to manage database transaction only, and no services or remote calls are involved, you can skip the potential issues related to MS DTC by using transaction native to databases (DbTransactions).

如果您的应用程序只需要管理数据库事务,并且不涉及任何服务或远程调用,则可以使用数据库本机事务 (DbTransactions) 跳过与 MS DTC 相关的潜在问题。

回答by Gediminas Bukauskas

TransactionScope supplies unified management for all resource mangers (SQL server, active directory, file system, …). Moreover, one can write own resource manager: code that detects transaction scope, join its and works exactly as SQL server does: commits or reverts changes like other participants of the transaction. I believed that TransactionScope is mainstream and forgot MS SQL native transactions until failed into huge trap: Windows Server 2008 WEB Edition comes with restricted Distributed Transaction Coordinator Service and Transaction scope works on single computer only.Your ASP.NET application will fail on this system if IIS and SQL server are installed on different computers. Take into account that most public domain providers supply Windows Server WEB edition and SQL server are on separate servers. This means, that you must work with native transactions using explicit transactions management …

TransactionScope 为所有资源管理器(SQL 服务器、活动目录、文件系统等)提供统一管理。此外,您可以编写自己的资源管理器:检测事务范围、加入其范围并与 SQL Server 完全一样工作的代码:像事务的其他参与者一样提交或恢复更改。我相信 TransactionScope 是主流,忘记了 MS SQL 原生事务,直到失败陷入巨大的陷阱: Windows Server 2008 WEB 版带有受限的分布式事务协调器服务,事务范围仅适用于单台计算机。如果 IIS 和 SQL 服务器安装在不同的计算机上,您的 ASP.NET 应用程序将在此系统上失败。考虑到大多数公共域提供商提供的 Windows Server WEB 版本和 SQL 服务器位于不同的服务器上。这意味着,您必须使用显式事务管理来处理本机事务……