【问题标题】:Wicket, authentication and transaction demarcation检票、身份验证和交易划界
【发布时间】: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


    【解决方案1】:

    这不是 Wicket 问题,而是 DB/Hibernate 问题。 Hibernate 有 support 用于乐观和悲观策略。

    optimistic approach 包括向实体添加一个version 字段,在刷新更新时将对其进行验证,如果有人修改了记录,则会引发异常。

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

    两者都有优点和缺点,都需要您积极使用相应的功能和代码才能使其工作(没有魔法灰尘)。

    乐观主义者将不得不处理任何可能出现的异常。

    悲观主义者将不得不处理争用和可扩展性问题。

    乐观主义者可能不得不改变架构结构和/或领域模型来处理某些情况。

    悲观主义者在处理对该表的更新时将不得不总是担心锁定(您忘记锁定在一个地方,而您刚刚创建了一个heisenbug)。

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

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多