nhibernate 中缺少对环境事务的支持?
我知道 NHibernate 支持环境事务,因为 NHibernate 会话在事务范围内时会加入环境事务。但是,有一些奇怪的地方,请考虑以下测试:
[Test]
public void Transaction_RollsBackTransactionInsideOfAmbientTransaction_AmbientTransactionAborted()
{
// arrange
ISessionFactory sessionFactory = SessionFactoryOneTimeInitializer.GetTestSessionFactory();
ISession session = sessionFactory.OpenSession();
SessionFactoryOneTimeInitializer.CreateDataBaseSchemaIfRequiredByConfiguration(session);
using (new TransactionScope())
{
using (ITransaction transaction = session.BeginTransaction())
{
// act
transaction.Rollback();
}
// assert
Assert.AreEqual(TransactionStatus.Aborted, Transaction.Current.TransactionInformation.Status);
}
}
该测试失败。 NHibernate 如何确保环境事务不会持久化到数据库?
I know NHibernate supports ambient transactions, because NHibernate sessions enlists in the ambient transactions while inside a transaction scope. However, there are some oddities, consider the following test:
[Test]
public void Transaction_RollsBackTransactionInsideOfAmbientTransaction_AmbientTransactionAborted()
{
// arrange
ISessionFactory sessionFactory = SessionFactoryOneTimeInitializer.GetTestSessionFactory();
ISession session = sessionFactory.OpenSession();
SessionFactoryOneTimeInitializer.CreateDataBaseSchemaIfRequiredByConfiguration(session);
using (new TransactionScope())
{
using (ITransaction transaction = session.BeginTransaction())
{
// act
transaction.Rollback();
}
// assert
Assert.AreEqual(TransactionStatus.Aborted, Transaction.Current.TransactionInformation.Status);
}
}
This test fails. How will NHibernate ensure that the ambient transaction is not persisted to the database?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我比较了解 Hibernate 如何在 Java 世界中与 JTA 配合使用,但我不是 .NET 专家。不过你的问题引起了我的注意。
在 Java 中,您需要使用 JDBC 或 JTA 事务配置 Hibernate。在这种情况下,Hibernate 返回的
Transaction
对象会包装绑定到一个数据库连接 (JDBC) 的事务或线程本地的全局事务。可以使用 < 使全局线程本地事务上下文失效code>UserTransaction#setRollbackOnly,这确保它永远不会成功提交。不过,最好不要通过 Hibernate 管理事务,而是仅使用 JTA 提供的 UserTransaction 对象。这在 NHibernate 中似乎仍然是相同的,并且有两个事务工厂。一种用于分布式事务一个用于本地事务。但两者都返回一个
AdoTransaction
:这在分布式/环境事务的情况下似乎不一致。鉴于全局事务上下文在 .NET 中不能无效(据我所知),我不知道在这种情况下回滚如何工作,并且 AdoTransaction 似乎表示数据库连接上的事务。
所以我觉得你的问题的答案是“不会”,这可以解释你的测试失败。这意味着如果您使用环境事务,则不应通过 NHirate 管理事务。就像 Hibernate 和 JTA 不推荐这样做一样。
编辑
另请参阅这个问题:TransactionScope 如何回滚事务?
I know relatively well how Hibernate work with JTA in the Java world, but I am not a .NET expert. Your question nevertheless caught my attention.
In Java, you need to configure Hibernate with either JDBC or JTA transaction. In which case, the
Transaction
object returned by Hibernate wraps either a transaction that is bound to one database connection (JDBC) or the global transaction that is thread-local. The global thread-local transaction context can be invalidated usingUserTransaction#setRollbackOnly
, which ensures it will never commit succesfully. It's however preferable to not manage transaction through Hibernate but to use solely theUserTransaction
object provided by JTA.This still seems to be the same in NHibernate and there is two transaction factories. One for distributed transactions and one for local transactions. But both return an
AdoTransaction
:This doesn't seem to be consistent in case of distributed / ambient transactions. I don't see how
rollback
would work in this case given that the global transaction context can not be invalided in .NET (so far I understand), andAdoTransaction
seems to represent a transaction on database connection.So I feel like the answer to your question is "it won't" which would explain that your test fails. This means that you should not manage transaction through NHiberate if you use ambient transaction. Just like it's not a recommended practice with Hibernate and JTA.
EDIT
See also this question: How does TransactionScope roll back transactions?