TransactionScope的好处/用途是什么?

4

我已经使用NHibernate一段时间了,发现以下代码使用了Transaction scope

using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
    using (var session = sessionFactory.OpenSession())
    {
       using (var transaction = session.BeginTransaction())
       {
         // do work
       }
     }
}

通常我在不将代码包装到TransactionScope中的情况下完成所有操作。我是否做错了什么或者我错过了一些很棒的功能?


请查看MSDN文档。http://msdn.microsoft.com/library/system.transactions.transactionscope(v=vs.110).aspx - Felipe Oriani
1
在所示的示例中,顺便说一下,事务实际上将在结束时回滚 - 没有任何内容会保存到数据库中。事务需要被提交scope.Complete(),如果我没记错的话)。 - Marc Gravell
4个回答

4

使用方法是: 事务。这是否有好处更为复杂。有更直接的方法来实现事务 - ADO.NET事务。这些方法使用起来有些麻烦(需要记住在每个命令上设置事务),但非常高效。

事务范围具有环境事务的优点;这使其更易于使用。但是,它的工作方式不同。特别地,事务范围支持多个资源事务 - 这可能意味着多个数据库等。通常通过DTC完成,但DTC 有开销 - 它更昂贵(并需要特定的防火墙配置等)。在许多单个数据库情况下,它可以通过LTM来捷径,而不是完整的DTC,但这仍比ADO.NET事务昂贵...只是没有DTC昂贵

一个强大的功能,但请确保您打算在使用之前使用它。;P


只是想提醒一下,在使用NHibernate时,关于为每个命令设置事务的尴尬并不真正适用,因为通常情况下,您永远不会直接处理IDbCommand。 - Oskar Berggren

1
如果您没有明确使用任何TransactionScope,那么您在数据库上执行的每个语句都将在单独的事务中运行。
通过使用TransactionScope,您可以将多个语句捆绑成一个大事务,并将所有操作作为一个块进行撤消。
这是必要的,当更新多个表格时,需要执行多个语句但实际上只是一个大操作,必须全部成功或者完全不做。

不,TransactionScope只是处理事务的一种方式。根据使用情况,在NHibernate中使用自己的事务(即定期的ADO.NET事务)而不是System.Transactions.Transaction完全有效。 - Oskar Berggren

1
您错过了一些美妙的功能:有了事务范围,如果从其自己的事务范围内运行的代码调用具有事务范围的代码,则具有事务范围的代码将参与环境事务。没有事务范围,您的代码将拥有自己的事务(来自最深嵌套块),该事务可能会失败而不会使外部事务失败。
此外,如果在其外部放置事务范围,则// do work块中的任何内容都可以更轻松地参与您的事务。该代码将能够打破您的事务,而无需将错误代码向上传播或抛出异常,这可能会被中间代码忽略。
注意:不要忘记在事务范围的using块结束之前调用scope.Complete()

如果我在事务范围内有两个事务,其中一个成功提交而另一个抛出异常,那么另一个成功的事务会回滚吗? - Cemre Mengü
@Cemre 如果您创建了一个嵌套事务并提交了它(而不仅仅是报告完成),那么就不会回滚。通常情况下,这不应该发生:每个附加到环境事务的范围都应该在不提交的情况下报告完成。实际提交命令将仅在最外层事务范围成功完成后发送给所有参与者。 - Sergey Kalinichenko
1
关于嵌套事务,一个嵌套在另一个事务中的事务通常不会被提交,这是由SQL服务器所看到的。正确的用法是在NHibernate事务超出范围之前调用commit,以确保它已将任何更改刷新到数据库。然而,在TransactionScope完成之前,SQL服务器内部的实际事务仍然保持未提交状态。 - Oskar Berggren

0

你是否在使用事务。如果没有,那么你应该使用它。

我个人在NHibernate中不使用TransactionScope,但是我也不需要它。在单个数据库的Web环境中,它并不是必需的。我的工作单元是一个Web请求。我在BeginRequest上打开连接,在EndRequest上关闭连接。我使用通用存储库,如果不存在,则会启动一个事务,并定义了一个TransactionAttribute来装饰控制器操作,以便所有表更新都在单个事务中执行。

TransactionScope只是微软将所有事务感知资源放入单个事务的通用方式。这可能是多个数据库,事务文件系统等。在这些情况下需要担心的事情是,事务很可能会升级到DTC以协调所有更新。

此外,我不知道它是否仍然存在问题,但早期版本的NHibernate使用TransactionScope会有与内存泄漏相关的问题。

这里有一个链接,包含关于TransactionScopes的所有信息 http://www.codeproject.com/Articles/690136/All-About-TransactionScope


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接