我有以下声明代码:
<tx:advice id="txAdvice" transaction-manager="TransactionManager">
<tx:attributes>
<tx:method name="Get"/>
<tx:method name="Update"/>
</tx:attributes>
</tx:advice>
我从函数“X”中调用方法“Get”和“Update”。
方法“Update”抛出异常“具有相同标识符值的不同对象已与 session 关联”
如何在Spring期间执行方法后关闭 session ?
更新信息:
我会尝试更准确地描述问题。
我有mvc项目。 Controller 调用管理器(它们代表业务逻辑)。管理人员使用存储库与数据库进行交互。 在更新操作中,我执行以下操作:
- 调用manager的Get方法获取Account
- 更改一些属性
- 调用管理器的 Update 方法来更新此帐户。
管理器的每个功能都被AOP包装成事务。 当我调用 Update 方法时,它会写入错误。看起来这是因为 Account 对象仍然附加到为 Get 函数打开的 session 。 我尝试直接在 Get 函数中打开和关闭 session (没有 AOP)。在这种情况下,所有工作都正确。
所以问题是为什么在 Get 调用之后 Account 对象仍然附加到 session ?
Imho you are not using Interfaces for your Repo and spring fails to build the AOP decorator.
我正在使用经理界面。我测试了事务的回滚。它有效,所以我认为 AOP 装饰器已经构建好了。
最佳答案
从对您问题的评论中,我了解到您的 AOP 代理配置正确。我知道你有一个这样的经理类:
public class Manager : ISomeInterfaceToProxy
{
object Get(...) {}
void Update(object toUpdate) {}
}
根据您的问题,建议此管理器类使用事务拦截器。
该管理器被注入(inject)到您的 Controller 中, Controller 首先调用 Get()
(启动并完成第一个事务),然后调用 Update(...)
。重要的是要认识到对 Update(...)
的调用会启动第二个事务,当 session 范围不是“per”时,这可能会导致您提到的错误要求”。如果没有找到 session ,则每个事务都会创建新 session 。
有几种解决方案:
- 确保您的 session 在整个网络请求期间保持打开状态,例如在 View 中使用打开 session ,如spring.net nhibernate session/transaction per request
- 从封装在事务建议中的另一个方法中调用
Get(...)
和Update(...)
例程,以便事务在方法调用之间传播
关于c# - Spring 在 nhibernate 事务后不关闭 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9583816/