我已经使用NHibernate一段时间了,并且遇到了使用Transaction scope
的代码。
using (var scope = new TransactionScope(TransactionScopeOption.Required))
{
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
// do work
}
}
}
我通常在没有将代码包装到TransactionScope
的情况下进行操作我是在做错了还是我错过了一些漂亮的功能?
答案 0 :(得分:3)
用法是:交易。这是否是利益更复杂。有更直接的方式来实现事务 - ADO.NET事务。使用它们有点尴尬(你需要记住在每个命令上设置事务),但效率很高。
交易范围具有环境交易的优势;这使得它更容易使用。但是,它以不同的方式工作。特别是,事务范围支持多个资源事务 - 这可能意味着多个数据库等。这通常通过DTC完成,但DTC 有开销 - 它更昂贵(和需要特定的防火墙配置等)。在许多单数据库的情况下,它可以缩短并使用LTM而不是完整的DTC,但这仍然比ADO.NET事务更昂贵......只是不像DTC那么昂贵
一项功能强大的功能,但请确保打算在使用之前使用它; p
答案 1 :(得分:1)
您错过了一些漂亮的功能:在事务范围到位的情况下,如果从在自己的事务范围内运行的代码内部调用,具有事务范围的代码将参与环境事务。如果没有事务范围,您的代码将拥有自己的事务(来自最深的嵌套块),该事务可能会失败而不会使外部事务失败。
此外,如果您将事务范围置于其外,// do work
块内的任何内容都将更容易参与您的事务。代码将能够破坏您的事务,而不必将错误代码传播到链中或抛出异常,这可能会被中间的代码忽略。
注意:不要忘记在scope.Complete()
块结束之前在事务范围上调用using
。
答案 2 :(得分:0)
如果您没有显式使用任何TransactionScope,则您在数据库上执行的每个语句都将在单独的事务中运行。
使用TransactionScope,您可以将多个语句捆绑到一个大事务中,并将所有内容作为一个块撤消。
这是必要的,当在多个语句中更新多个表但执行几乎一件大事时,必须工作或根本不工作。
答案 3 :(得分:0)
您是否正在使用交易?如果你不是,那么你应该是。
我个人不在任何NHibernate中使用TransactionScope,但我不再需要它。在具有单个数据库的Web环境中,实际上并不是必需的。我的工作单位是网络请求。我在BeginRequest上打开我的连接并在EndRequest上关闭它。我使用一个通用存储库,如果不存在则会启动转换,并定义一个TransactionAttribute来装饰控制器操作,以便在单个事务中执行所有表更新。
TransactionScope只是Microsoft将所有事务感知资源放入单个事务的通用方法。这可能是多个数据库,一个事务性文件系统,......在这些情况下需要担心的是,事务很可能会被提升到DTC以协调所有更新。
此外,我不知道它是否仍然存在问题,但旧版本的NHibernate曾经因使用TransactionScope而导致内存泄漏。
以下是您需要了解的有关TransactionScopes http://www.codeproject.com/Articles/690136/All-About-TransactionScope
的所有信息的链接