使用 Castle AutoTx 设施和 NHibernate 设施的事务
我正在尝试将 Castle NHibernate 设施 与 AutoTx 设施一起使用。作为测试,我在服务中间抛出异常,以确保事务回滚。但是,数据仍然保留在数据库中。
我的服务接口 IActivityService
使用 TransactionAttribute:
public interface IActivityService
{
[Transaction]
Activity CreateActivity(Activity activity);
}
CreateActivity
的实现。我在这里抛出一个异常,期望回滚 AddActivity
中添加的数据:
public virtual Activity CreateActivity(Activity activity)
{
activityDAO.AddActivity(activity);
throw new Exception("This should rollback the transaction");
return activity;
}
AddActivity
的实现。 SessionManager
是一个注入的ISessionManager
。
public void AddActivity(Activity activity)
{
using (ISession session = SessionManager.OpenSession())
{
session.Save(activity);
}
}
最后,这是我配置 Windsor 容器的方法。 NHibernateInstaller
直接来自 指南,交换了我流畅的nhibernate配置:
container = new WindsorContainer().Install(FromAssembly.This());
// set up ISessionManager injection for DAOs
container
.AddFacility<AutoTxFacility>()
.Register(Component
.For<INHibernateInstaller>()
.ImplementedBy<NHibernateInstaller>()
.LifeStyle.Singleton)
.AddFacility<NHibernateFacility>(f =>
f.DefaultLifeStyle = DefaultSessionLifeStyleOption.SessionPerWebRequest);
配置看起来相当简单,但我不知道我错过了什么。感谢您的任何帮助。
I'm trying to use the Castle NHibernate Facility with the AutoTx Facility. As a test, I'm throwing an exception in the middle of my service, to make sure the transaction is rolled back. However, the data is still persisted in the database.
My service interface, IActivityService
using the TransactionAttribute:
public interface IActivityService
{
[Transaction]
Activity CreateActivity(Activity activity);
}
The implementation of CreateActivity
. I'm throwing an exception here, expecting the data added in AddActivity
to be rolled back:
public virtual Activity CreateActivity(Activity activity)
{
activityDAO.AddActivity(activity);
throw new Exception("This should rollback the transaction");
return activity;
}
Implementation of AddActivity
. SessionManager
is an injected ISessionManager
.
public void AddActivity(Activity activity)
{
using (ISession session = SessionManager.OpenSession())
{
session.Save(activity);
}
}
Finally, here's how I'm configuring the windsor container. The NHibernateInstaller
is straight from the guide, with my fluent nhibernate configuration swapped in:
container = new WindsorContainer().Install(FromAssembly.This());
// set up ISessionManager injection for DAOs
container
.AddFacility<AutoTxFacility>()
.Register(Component
.For<INHibernateInstaller>()
.ImplementedBy<NHibernateInstaller>()
.LifeStyle.Singleton)
.AddFacility<NHibernateFacility>(f =>
f.DefaultLifeStyle = DefaultSessionLifeStyleOption.SessionPerWebRequest);
The configuration seemed fairly straightforward, but I can't figure out what I'm missing. Thanks for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您没有显示服务实现类的类声明代码,因此您可能已经这样做了,但如果您想要声明式事务,则需要使用
[Transactional]
属性注释事务类。如果您不在实现类中包含 [Transactional] 属性,则 AutoTx 工具不知道为该类创建包装器。
我倾向于将
[Transaction]
属性放在实现方法上,而不是放在接口定义中。我不知道注释接口方法声明是否有效。您可能还需要尝试一件事。我注意到,当您配置容器时,您首先要安装,然后添加 AutoTx 设施。我认为您应该在调用安装程序之前先添加设施。
You do not show the class declaration code for the service implementation class, so you might have already done this, but if you want declarative transactions, you need to annotate the transaction class with the
[Transactional]
attribute.If you do not include the [Transactional] attribute on the implementing class, the AutoTx facility does not know to create a wrapper for the class.
I tend to put the
[Transaction]
attribute on the implementing method, not in the interface definition. I don't know if it works annotating the interface method declaration.One more thing you might need to try. I notice that when you are configuring your container, you are installing first, and then adding the AutoTx facility. I think you should add the facilities first before invoking your installers.
首先,会话管理器和活动服务之间必须具有直接依赖关系。会话管理器应该注入到活动服务中。只有在这种情况下该设施才能影响 NHibernate 事务。
还要检查您是否对 SessionManager、服务器、DAO 和其他依赖对象使用相同的生活方式。
At first you must have direct dependencies between Session Manager and Activity Service. Session manager should be injected into Activity Service. Only in this case the facility can affect NHibernate transaction.
Also check that you are using same life styles for SessionManager, Server, DAOs and other dependent objects.