【问题标题】:Is concurrent synchronization on JPA entity's transient fields necessary?JPA 实体的瞬态字段上的并发同步是否必要?
【发布时间】:2013-04-28 06:10:27
【问题描述】:

我们知道两个线程同时操作同一个实体,如果所有默认值都适用,将抛出OptimisticLockException。如果线程操作的字段被标记为注释@Transient 或修饰符transient,会发生什么?

我的直觉是持久化提供者不会打扰我们对瞬态字段做什么以及如何访问它们。这进一步告诉我,如果我们认为在我们的应用程序中足够重要,则应该将同步机制应用于这些领域。

但是,我已经在 Google 上搜索了我所有的 Java EE 书籍和 JPA 2.0 规范,但我找不到这个“问题”得到解决。这告诉我我一定是在这里遗漏了什么并且我过度担心了??

【问题讨论】:

    标签: jakarta-ee jpa concurrency transient


    【解决方案1】:

    OptimisticLockException 仅在实体中有 @Version 字段时使用,并且如果事务尝试保存自加载实体状态以来已被另一个事务修改的实体。

    每个事务都有它自己加载的每个实体的实例。实体不是线程安全的,不能被多个线程共享。

    JPA 确实完全忽略了瞬态字段。但我看不出同步如何改变任何东西,因为每个线程都有自己的实体实例。此外,在大多数企业应用程序中,多个 JVM 使用同一个数据库,因此同步在这方面无济于事。坦率地说,在实体中使用瞬态字段通常会显示设计问题,并且依靠实体中瞬态字段的状态来保持由多个线程共享的状态是完全错误的。如果状态是由多个线程甚至进程共享的,那么它可能应该保存在数据库中。

    【讨论】:

    • 考虑我们有一个@Singleton,也标有@ConcurrencyManagement(ConcurrencyManagementType.BEAN)的情况。远程客户端、Servlet 和其他 EJB:s 都使用这个单例......很多。单例管理 [分离] 实体的集合。每个实体都有对另一个实体的临时引用。该关系只是当前应用程序状态的一部分。这样,线程不共享分离的实体引用吗?如果它在语义上是正确的,假设一个实体是一个正在与另一个人聊天的人,你还会认为这是一个糟糕的设计吗?
    • 分离的实体只不过是一个普通的旧 Java 对象。与任何其他对象相同的并发规则适用于它们。因此它与 JPA 没有任何关系,并且属性是否是瞬态的也无关紧要。如果您有这样的设计,那么请阅读一般的并发和线程安全。不要在 JPA 中寻找答案,因为 JPA 在这种情况下是无关紧要的。
    • 谢谢 JB Nizet,非常感谢。但是,我不同意分离的实体只不过是 POJO。请参阅 JPA 2.0 规范,第79:“分离的实体实例 [..] 不再保证与数据库状态同步”。这个词是“保证的”。 “Pro JPA 2”一书在第 1 页上说。 160:如果我们访问他的延迟加载属性,“一些供应商可能会尝试解决分离实体的关系”。 EntityManager#merge 的 JavaDocs 接受“实体实例”。本质上你是对的。以为我只是指出了第三方的一些细微差别。
    猜你喜欢
    • 2018-03-27
    • 1970-01-01
    • 2016-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    • 2012-05-06
    相关资源
    最近更新 更多