Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/google-chrome/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# TransactionScope的好处/用途是什么?_C#_Nhibernate_Transactionscope - Fatal编程技术网

C# TransactionScope的好处/用途是什么?

C# TransactionScope的好处/用途是什么?,c#,nhibernate,transactionscope,C#,Nhibernate,Transactionscope,我已经使用NHibernate有一段时间了,我发现下面的代码使用了事务范围 using (var scope = new TransactionScope(TransactionScopeOption.Required)) { using (var session = sessionFactory.OpenSession()) { using (var transaction = session.BeginTransaction()) {

我已经使用NHibernate有一段时间了,我发现下面的代码使用了
事务范围

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

我通常不将代码包装到TransactionScope,而是执行所有操作。我是做错了什么,还是错过了一些漂亮的功能?

如果没有明确使用任何TransactionScope,那么在数据库上执行的每一条语句都将在单独的事务中运行

使用TransactionScope,您可以将多个语句捆绑到一个大事务中,并将所有语句作为一个块撤消


当在多个语句中更新多个表,但实际上执行一件大事时,这是必要的,这件事要么起作用,要么根本不起作用

您错过了一些漂亮的功能:有了事务作用域,如果从运行在自己事务作用域中的代码段内部调用,则具有事务作用域的代码将参与环境事务。如果没有事务作用域,代码将有自己的事务(来自最深的嵌套块),该事务可能会失败,而不会使外部事务失败

此外,如果将事务范围放在
//do work
块之外,则
//do work>块内的任何内容都可以更轻松地参与事务。代码可以在不必将错误代码传播到链或抛出异常的情况下中断事务,这可能在中间被代码忽略。


注意:不要忘记在事务作用域的
块结束之前调用
作用域.Complete()

是否使用事务。如果你不是,那么你应该是

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

TransactionScope只是Microsoft将所有事务感知资源放入单个事务的通用方法。这可能是多个数据库、事务性文件系统等。。。。在这些场景中需要担心的是,事务很可能会升级到DTC以协调所有更新

另外,我不知道这是否仍然是一个问题,但NHibernate的旧版本曾经有一个与使用TransactionScope相关的内存泄漏

这里有一个链接,您需要了解有关TransactionScopes的所有信息。用法是:transactions。这是否有益则更为复杂。有更直接的实现事务的方法—ADO.NET事务。使用这些命令有点笨拙(您需要记住在每个命令上设置事务),但它们非常有效

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


这是一个强大的功能,但在使用之前要确保你打算使用它;p

查看MSDN文档。在所示的示例中,顺便说一句,事务实际上会在最后回滚—不会将任何内容保存到数据库中。需要提交事务(
scope.Complete()
,IIRC)如果在事务范围内有两个事务,而其中一个成功提交,另一个抛出异常,该怎么办。另一个成功的事务是否会回滚?@Cemre如果您创建一个提交的嵌套事务(而不是简单地报告完成),则不会回滚。但是,通常情况下,这种情况不应该发生:附加到环境事务的每个作用域都会报告完成而不提交。只有在最外层事务作用域成功完成时,才会将实际提交的命令发送给所有参与者。@Cemre关于嵌套事务,嵌套在另一个事务中的事务通常不会提交,如SQL server所示。正确的用法是在NHibernate事务超出范围之前调用commit,以确保它已刷新对数据库的任何更改。但是,在TransactionScope完成之前,SQL server内部的实际事务仍将保持未提交状态。请注意,在使用NHibernate时,为每个命令设置事务的尴尬并不真正适用,因为通常您永远不会直接处理IDB命令。否,TransactionScope只是处理事务的一种方式。根据用例的不同,使用NHibernate自己的事务(即常规ADO.NET事务)而不是System.transactions.Transaction是完全有效的。