3

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

的实施AddActivitySessionManager是注入的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);

配置看起来相当简单,但我不知道我错过了什么。谢谢你的帮助。

4

2 回答 2

1

首先,您必须在 Session Manager 和 Activity Service 之间有直接的依赖关系。会话管理器应该被注入到活动服务中。只有在这种情况下,该工具才能影响 NHibernate 事务。

    [交易]
    公共类 ActionService : IActionService
    {
        私人 ISessionManager _sessionManager;

        [交易]
        公共无效AddActivity(活动活动)
        {
            使用 (ISession 会话 = _sessionManager.OpenSession())
            {
                使用 (ITransaction tran = session.BeginTransaction())
                {
                        session.Save(活动);
                    tran.Commit();
                }
            }       
        }
        公共 ActionService(ISessionManager sessionManager)
    {
            _sessionManager = 会话管理器;       
        }
    }
    _container.Register(Component.For<IActionService>()
            .ImplementedBy<ActionService>.LifestylePerWebRequest());

还要检查您是否对 SessionManager、Server、DAO 和其他依赖对象使用相同的生活方式。

于 2011-12-13T02:23:36.390 回答
1

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

[Transactional]    
public class ActivityServiceImpl {

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

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

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

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

于 2011-12-15T01:53:45.943 回答