我尝试将Castle NHibernate Facility与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
直接来自the guide,我的流利的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);
配置似乎相当简单,但我无法弄清楚我错过了什么。谢谢你的帮助。
答案 0 :(得分:1)
首先,您必须在会话管理器和活动服务之间具有直接依赖关系。应将会话管理器注入活动服务。只有在这种情况下,工具才会影响NHibernate事务。
[Transactional] public class ActionService : IActionService { private ISessionManager _sessionManager; [Transaction] public void AddActivity(Activity activity) { using (ISession session = _sessionManager.OpenSession()) { using (ITransaction tran = session.BeginTransaction()) { session.Save(activity); tran.Commit(); } } } public ActionService(ISessionManager sessionManager) { _sessionManager = sessionManager; } } _container.Register(Component.For<IActionService>() .ImplementedBy<ActionService>.LifestylePerWebRequest());
同时检查您是否对SessionManager,Server,DAO和其他依赖对象使用相同的生活方式。
答案 1 :(得分:1)
您没有显示服务实现类的类声明代码,因此您可能已经完成了此操作,但如果您需要声明性事务,则需要使用[Transactional]
属性注释事务类。
[Transactional]
public class ActivityServiceImpl {
[Transaction]
public Activity CreateActivity(Activity activity) {
// ... implementation here
}
}
如果在实现类中不包含[Transactional]属性,则AutoTx工具不知道为该类创建包装器。
我倾向于将[Transaction]
属性放在实现方法上,而不是在接口定义中。我不知道它是否可以注释接口方法声明。
您可能还需要尝试一件事。我注意到在配置容器时,首先安装,然后添加AutoTx工具。我认为您应该在调用安装程序之前先添加设施。