我正在尝试将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);

配置似乎相当简单,但我无法弄清楚我错过了什么。 谢谢你的帮助。

===============>>#1 票数: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和其他依赖对象使用相同的生活方式。

===============>>#2 票数:1 已采纳

您没有显示服务实现类的类声明代码,因此您可能已经这样做了,但是如果您需要声明性事务,则需要使用[Transactional]属性来注释事务类。

[Transactional]    
public class ActivityServiceImpl {

    [Transaction]
    public Activity CreateActivity(Activity activity) {
        // ... implementation here
    }
}

如果在实现类中不包含[Transactional]属性,则AutoTx工具不知道为该类创建包装器。

我倾向于将[Transaction]属性放在实现方法上,而不是在接口定义中。 我不知道它是否有效地注释接口方法声明。

还有一件事你可能需要尝试。 我注意到在配置容器时,首先安装,然后添加AutoTx工具。 我认为您应该在调用安装程序之前先添加设施。

  ask by Will translate from so

未解决问题?本站智能推荐: