Java Wicket、身份验证和事务划分

Java Wicket、身份验证和事务划分,java,hibernate,spring,wicket,Java,Hibernate,Spring,Wicket,我正在使用Wicket和一个定制的PageAuthorizationStrategy,它访问数据库以获取当前用户的信息,从而获得他的访问权限。每个请求都由视图过滤器中的Spring Open会话包装,以打开/关闭Hibernate会话 这非常适用于对数据库的读取访问。但是,每当需要执行写入操作时,我都会调用服务层,它使用Spring基于注释的事务处理。这也是可行的,但我认为这是一个特定错误的原因:当在请求a中的身份验证期间加载对象,然后在另一个请求B中修改,然后在请求a中移交给服务层时,服务层正

我正在使用Wicket和一个定制的PageAuthorizationStrategy,它访问数据库以获取当前用户的信息,从而获得他的访问权限。每个请求都由视图过滤器中的Spring Open会话包装,以打开/关闭Hibernate会话

这非常适用于对数据库的读取访问。但是,每当需要执行写入操作时,我都会调用服务层,它使用Spring基于注释的事务处理。这也是可行的,但我认为这是一个特定错误的原因:当在请求a中的身份验证期间加载对象,然后在另一个请求B中修改,然后在请求a中移交给服务层时,服务层正在使用错误的值,因为Hibernate和底层数据库都不能确保隔离。由于我一直在为数据库/事务理论的细节而挣扎,如果这个假设已经错了,请纠正我

我对解决方案的第一个想法是在写入事务启动后立即刷新加载用于身份验证的对象。但是,当服务修改的对象同时需要进行身份验证时,这会导致问题。当Wicket使用表单中更改的数据填充对象并以submit方法(例如)将其传递给服务时,尤其会发生这种情况

因此,这样做的正确方法可能是确保身份验证代码已经与可能在同一请求期间执行的任何编写代码包装在同一事务中

我该如何在Wicket以“正确的方式”处理这件事


编辑:当我意识到在抛出异常后事务处理服务方法回滚时,视图层会导致LazyInitializationException,因此这个问题变得更为严重。显然,Spring的TransactionManager会清除会话和/或Hibernate/Spring深处的其他内容,因为我可以从数据库重新加载对象,但尝试加载该对象中包含的集合会导致上述异常。你知道怎么做吗?我想,如果有一种优雅的方式来使用“每个请求一个事务”,这一切都会得到解决。

我不确定这是否是Wicket中“正确方式”的问题,我会尝试在服务/dao层中解决这一问题,有以下几种可能性:

  • 不要对“实时”所需的信息使用OSIV模式,OSIV在表上显示项目信息时会发光,而无需查询数据库
  • 将编辑/更改的属性附加到对象上,例如上次更改的时间戳,在执行任何写入操作之前,您可以检查时间戳并警告/补偿来自“未来”的更改

    • 这不是Wicket问题,而是DB/Hibernate问题。Hibernate对乐观和悲观策略都有自己的优势

      其中包括向实体添加一个
      version
      字段,刷新更新时将对该字段进行验证,如果有人修改了记录,则会导致异常

      使用数据库支持锁定记录,避免并发修改

      两者都有优点和缺点,并且都要求您积极地使用相应的特性和代码,以使其工作(没有魔法灰尘)

      乐观主义者必须处理任何可能出现的例外情况

      悲观主义者将不得不处理争用和可伸缩性问题

      乐观主义者可能必须改变模式结构和/或域模型来处理某些情况

      悲观主义者在处理该表的更新时必须始终担心锁定问题(您忘记了在一个位置锁定,并且您刚刚创建了一个新表)

      NoSQL人员会告诉他们完全放弃关系数据库,并在没有模式、事务和一致性的情况下快乐地生活(顺便说一句,这在大多数情况下是愚蠢的)