【问题标题】:How do I make my pojos transactional?如何使我的 pojo 具有交易性?
【发布时间】:2009-09-22 16:10:29
【问题描述】:

我有一个多线程、多服务器的 Web 应用程序,它带有休眠和使用 AOP 管理事务的弹簧。问题是,我需要维护内存中的数据并使其与数据库的状态保持同步……基本上我正在实现内存中的缓存。

现在,有什么方法可以让我的内存中 pojos 在与 hibernate/spring 事务性相同的级别上进行事务处理?我有分层 30 个类的服务调用,但我永远不知道提交会发生在哪里。我有哪些选择?

【问题讨论】:

    标签: hibernate spring transactions pojo


    【解决方案1】:

    如果我能很好地理解您的需求,那么在某些情况下,您是在问一些微妙的问题。让我尝试一个示例,以检查我是否理解正确

    1. 线程 T1 读取缓存中的 pojo P,获取版本 P1。
    2. 线程 T2 读取缓存中的 pojo P,获取版本 P1。
    3. 线程 T2 启动事务,读取相同的 pojo,修改创建版本 P​​2 的值。
    4. 线程 T1 读取缓存中的 pojo P,仍然获取版本 P1。这要求对于第 3 点,T2 收到版本 P1 的副本 P2,而不是同一个对象。
    5. 线程 T2 保存 P,T1 或 T2 没有任何变化,它们有不同的版本。
    6. 线程 T2 关闭事务:
      一种。如果回滚,则 T2 将像 T1 一样使用 P1。
      湾。如果提交,T2 将继续使用 P2。但现在 T1 也必须使用 P2。

    您可以看到这是一个复杂的问题,不要低估它。 在理论层面上已经有很多问题需要解决(当你编写代码时你会有更多问题......)。 如果您想成功使用它,您的架构需要非常清晰。 如果没有,你会冒着精神失常的风险;-)

    首先,你需要确定你真的想要这样的东西!


    如果你真的想要那个..

    我建议使用技术代码(AOP、ThreadLocal)从你的函数代码中隐藏这个棘手的复杂性

    • 很可能你的提交/回滚已经通过 AOP 完成了,所以应该没问题。

    • 要隐藏 P 实例的检索(有时是存储缓存中的实例,有时是副本):使用名为 Store 的类将值存储在缓存中,具有 Store 类型的 ThreadLocal 变量。我会为您当前的线程使用 ThreadLocal 变量:

      • 只能在事务性 AOP 代码中更改 Store 实例,而不能在功能代码中更改
      • 您的功能代码使用当前的 ThreadLocal 实例来操作实体(保存等)
      • 事务外时,ThreadLocal 实例是缓存的,我们称之为CACHE。
      • 进入事务为当前线程设置不同的 ThreadLocal 实例;该类是 Store 的子类,它将根据您的要求返回缓存对象的副本;如果保存了一些,该类也会记住(因此您需要使用此特殊 API 保存它们,或在您的常规保存 API 中通知)
      • 回滚事务会丢弃 ThreadLocal 实例,为当前线程重新安装 CACHED 实例
      • 提交一个事务会在 ThreadLocal 实例中获取所有记忆的数据库操作,将其应用于修改 CACHED 实例,并为当前线程重新安装 CACHED 实例

    【讨论】:

      【解决方案2】:

      使用 Hibernate 的2nd level cache 不能满足您的要求吗? JBoss Cache 提供程序既是分布式的又是事务性的。

      如果这对您不起作用,您必须解释为什么以及您真正想要实现的目标是什么,以便获得有意义的响应。

      【讨论】:

        猜你喜欢
        • 2018-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-19
        • 1970-01-01
        • 2023-03-14
        • 1970-01-01
        相关资源
        最近更新 更多