【问题标题】:Transactions using Castle AutoTx Facility and NHibernate Facility使用 Castle AutoTx Facility 和 NHibernate Facility 的交易
【发布时间】:2011-12-11 20:34:07
【问题描述】:

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

配置看起来相当简单,但我不知道我缺少什么。感谢您的帮助。

【问题讨论】:

    标签: .net nhibernate transactions castle-windsor windsor-nhfacility


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 啊,你在两个方面是对的,谢谢!我必须在调用安装程序之前添加设施,并且[Transaction] 必须在实施中。顺便说一句,[Transactional] 属性已被弃用(我正在运行 Castle.Services.Transaction.3.0.202.2202);没有它也能正常工作。
    【解决方案2】:

    首先你必须在 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() .ImplementedBy.LifestylePerWebRequest());

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

    【讨论】:

    • 感谢您的回复。在您的示例中,我看到您正在手动管理事务。不应该使用 AutoTx 工具意味着我不需要它吗?
    • 我又检查了一次城堡源,我没有看到任何 NHibernate 事务可管理性集成。文档说“这个工具通常与其他工具一起工作,因为它需要实现 ITransactionManager。目前 ActiveRecord 集成工具、NHibernate 工具和 iBatis.Net 工具实现了 ITransactionManager。”但是 NHibernate 工具没有实现某个,它只在容器中注册 DefaultTransactionManager。您可以使用 nhprof 实用程序进行检查:它会说您“不鼓励使用隐式事务”。
    猜你喜欢
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    相关资源
    最近更新 更多