hibernate - 如何使我的 pojo 具有事务性?

标签 hibernate spring transactions pojo

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

现在,有什么方法可以使我的内存中 pojos 事务性与 hibernate/spring 事务性处于同一级别?我有 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 变量:

    • Store 实例只能在您的事务性 AOP 代码中更改,不能在您的功能代码中更改
    • 您的功能代码使用当前的 ThreadLocal 实例来操作实体(保存等...)
    • 在事务之外时,ThreadLocal 实例是缓存的实例,我们称它为缓存。
    • entering a transaction 为当前线程设置一个不同的 ThreadLocal 实例;该类是 Store 的子类,它将在您请求时返回缓存对象的副本;该类还将记住是否保存了一些内容(因此您需要使用这个特殊的 API 来保存它们,或者在您的常规保存 API 中通知这一点)
    • 回滚事务会丢弃 ThreadLocal 实例,为当前线程重新安装 CACHED 实例
    • 提交事务将采用 ThreadLocal 实例中所有存储的数据库操作,应用它来修改 CACHED 实例,并为当前线程重新安装 CACHED 实例

关于hibernate - 如何使我的 pojo 具有事务性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1461039/

相关文章:

Hibernate:如何自动将java对象映射到两列上?

java - Hibernate 关闭 MySQL 连接

java - 如何强制*立即*将新记录保存到数据库中?

php - 如何在 mysqli 中开始和结束事务?

java - Quartz @DisallowConcurrentExecution 允许类的多个实例运行但不允许作业?

java - 一个事务可以有多个线程吗?

java - 绕过 PUT 请求的唯一性 validator

hibernate - 如何将多个值传递给也与其他参数相对应的参数?

java - 如何使用多个 POJO 更新数据库中的同一个表?

spring - Grails邮件插件:附加org.springframework.web.multipart.commons.CommonsMultipartFile