休眠-如何使Pojos具有事务性?

我有一个多线程,多服务器的Web应用程序,它具有使用AOP进行休眠和春季管理事务的功能.问题是,我需要维护内存中的数据并使其与数据库状态保持最新……本质上,我正在实现内存中的缓存.

现在,有什么方法可以使我的内存pojos具有与休眠/春季事务性相同的事务性吗?我在深处有30个类的服务调用,但我永远不知道将在哪里进行提交.我有什么选择?

解决方法:

如果我了解您的需求,那么您在某些情况下会提出一些微妙的问题.让我尝试一个例子,检查我是否正确理解:

  1. Thread T1 reads pojo P in the cache, gets version P1.
  2. Thread T2 reads pojo P in the cache, gets version P1.
  3. Thread T2 starts transaction, read the same pojo, modify a value which creates version P2.
  4. Thread T1 reads pojo P in the cache, still gets version P1. This requires that for point 3, T2 received a copy P2 of version P1, not the same object.
  5. Thread T2 saves P, nothing changes for either T1 or T2, they have different versions.
  6. Thread T2 closes the transaction:
    a. if rollback, T2 will then use P1, as T1 does.
    b. if commit, T2 will continue using P2. But now T1 must use P2 also.

您可以看到这是一个复杂的问题,请不要小看.
从理论上讲,有许多问题需要解决(编写代码时还会有更多问题……).
如果要成功使用它,您的体系结构将需要非常清楚.
如果没有,您就有精神错乱的风险;-)

首先,您需要确保您确实想要这样的东西!

如果你真的想要..

我建议使用技术代码(AOP,ThreadLocal)来从功能代码中隐藏这种棘手的复杂性.

>您的提交/回滚很可能已经通过AOP完成,因此这应该没问题.
>要隐藏对P实例的检索(有时,该实例在“存储的缓存”中,有时是一个副本):使用名为Store的类将值存储在缓存中,具有类型为Store的ThreadLocal变量.我将对当前线程使用ThreadLocal变量:

>只能在您的事务性AOP代码中而不是在功能代码中更改Store实例
>您的功能代码使用当前的ThreadLocal实例来操纵实体(保存等).
>在事务之外,ThreadLocal实例是已缓存的实例,我们将其称为CACHE.
>输入事务为当前线程设置一个不同的ThreadLocal实例;该类是Store的子类,它将根据您的请求返回缓存对象的副本;该课程还将记住是否保存了某些内容(因此您需要使用此特殊API保存它们,或在常规保存API中进行通知)
>回滚事务将丢弃ThreadLocal实例,为当前线程重新安装CACHED实例
>提交事务将占用ThreadLocal实例中所有已存储的数据库操作,将其应用于修改CACHED实例,然后为当前线程重新安装CACHED实例

上一篇:【从零开始学SpringMVC笔记】参数绑定


下一篇:resultMap的使用总结