在nhibernate事务之后,Spring不会关闭会话

时间:2012-03-06 12:34:52

标签: c# asp.net-mvc nhibernate fluent-nhibernate spring.net

我有以下声明代码:

<tx:advice id="txAdvice" transaction-manager="TransactionManager">
    <tx:attributes>
        <tx:method name="Get"/>
        <tx:method name="Update"/>
    </tx:attributes>
</tx:advice>

我从函数“X”调用方法“Get”和“Update”。

方法“更新”抛出异常“具有相同标识符值的不同对象已与会话相关联”

如何在执行方法后关闭Spring期间的会话?

更新信息

我会尝试更准确地描述问题。

我有mvc项目。 Conrolers致电经理(他们代表业务逻辑)。管理员使用存储库与db进行交互。 在更新操作中,我执行以下操作:

  • 调用获取帐户的获取方法
  • 改变一些特色
  • 调用管理器的更新方法以升级此帐户。

经理的每个职能都由AOP包含在交易中。 当我调用Update方法时,它会写入错误。看起来这是因为Account对象仍然附加到为Get函数打开的会话。 我试图直接在Get函数中打开和关闭会话(没有AOP)。在这种情况下,所有工作都是正确的。

所以问题是为什么在Get调用之后,Account对象仍然附加到会话?

  

Imho你没有为你的Repo使用Interfaces而且spring无法构建AOP装饰器。

我正在为经理使用接口。我测试了事务的回滚。它有效,所以我认为AOP装饰器是构建的。

1 个答案:

答案 0 :(得分:2)

从评论到您的问题,我了解您的AOP代理已正确配置。我知道你有这样一个经理班:

public class Manager : ISomeInterfaceToProxy
{
  object Get(...) {}
  void Update(object toUpdate) {}
}

此经理类会根据您的问题通知事务拦截器。 该管理器将注入您的控制器,该控制器首先调用Get()(启动并完成第一个事务),然后调用Update(...)。重要的是要意识到Update(...)上的调用会启动第二个事务,这可能会导致您在会话范围不是“按请求”时提到的错误。如果找不到会话,则每个事务都将创建新会话。

有几种解决方案:

  1. 确保您的会话在整个网络请求期间保持打开状态,例如:在spring.net nhibernate session/transaction per request
  2. 中使用视图中的开放会话
  3. 从包含在事务通知中的另一个方法中调用Get(...)Update(...)例程,以便在方法调用之间传播事务