【发布时间】:2011-06-16 15:40:43
【问题描述】:
我正在使用带有自定义 PageAuthorizationStrategy 的 Wicket,它访问数据库以获取有关当前用户的信息以及他的访问权限。每个请求都由 Spring Open-Session-In-View 过滤器包装,以打开/关闭 Hibernate 会话。
这非常适用于对数据库的读取访问。但是,每当需要进行编写操作时,我都会调用使用 Spring 的基于注释的事务处理的服务层。这也有效,但我认为这是导致特定错误的原因:当在请求 A 中的身份验证期间加载对象,然后在另一个请求 B 中修改,然后在请求 A 中移交给服务层时,服务层正在使用错误的值,因为 Hibernate 和底层数据库都不能确保隔离。由于我总是在数据库/事务理论的细节上苦苦挣扎,如果这个假设已经错误,请纠正我。
我对解决方案的第一个想法是在写入事务开始后立即刷新加载以进行身份验证的对象。这会导致问题,但是当需要由服务修改的对象同时需要进行身份验证时。当 Wicket 使用表单中的更改数据填充对象并在提交方法中将其传递给服务时(例如),尤其会发生这种情况。
因此,这样做的正确方法可能是确保身份验证代码已经包装在与可能在同一请求期间执行的任何编写代码相同的事务中。
我将如何在 Wicket 中以“正确的方式”解决这个问题?
编辑:这个问题变得更加严重,因为我意识到当事务服务方法在抛出异常后回滚时,视图层会导致 LazyInitializationException。显然,Spring 的 TransactionManager 清除了会话和/或 Hibernate/Spring 深处的其他东西出错了,因为我可以从数据库中重新加载一个对象,但尝试加载该对象中包含的集合会导致上述异常。任何想法如何去做?我想如果有一种优雅的方式来使用“每个请求一个事务”,这一切都会得到解决。
【问题讨论】:
标签: java hibernate spring wicket