我有以下声明代码:
<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装饰器是构建的。
答案 0 :(得分:2)
从评论到您的问题,我了解您的AOP代理已正确配置。我知道你有这样一个经理班:
public class Manager : ISomeInterfaceToProxy
{
object Get(...) {}
void Update(object toUpdate) {}
}
此经理类会根据您的问题通知事务拦截器。
该管理器将注入您的控制器,该控制器首先调用Get()
(启动并完成第一个事务),然后调用Update(...)
。重要的是要意识到Update(...)
上的调用会启动第二个事务,这可能会导致您在会话范围不是“按请求”时提到的错误。如果找不到会话,则每个事务都将创建新会话。
有几种解决方案:
Get(...)
和Update(...)
例程,以便在方法调用之间传播事务