2013-05-03 51 views
1

我们知道两个线程同时操作同一个实体,如果所有默认值都适用,则会抛出OptimisticLockException。如果线程操作的字段出现了注释@Transient或修饰符transient,会发生什么情况?是否需要在JPA实体的瞬态字段上同步同步?

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

但是,我使用了所有的Java EE书籍和JPA 2.0规范,但找不到这个“问题”。这告诉我,我必须在这里失去一些东西,我很担心?

回答

1

OptimisticLockException将仅在实体中存在@Version字段时使用,并且如果事务尝试保存由于实体的状态已加载而被另一事务修改的实体,则将使用OptimisticLockException。

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

瞬时字段确实被JPA完全忽略。但我不明白同步如何改变任何事情,因为每个线程都有自己的实体实例。而且,在大多数企业应用程序中,多个JVM使用相同的数据库,因此同步对此没有帮助。坦率地说,在实体中使用瞬态字段通常会显示设计问题,并且依赖实体中瞬态字段的状态来保持多线程共享的状态显然是错误的。如果状态由多个线程或甚至进程共享,则应该将其保存在数据库中。

+0

考虑一下我们有'@ Singleton'的情况,它也标有'@ConcurrencyManagement(ConcurrencyManagementType.BEAN)'。远程客户端,Servlet和其他EJB:都使用这个单例..很多。单身人员管理[分离]实体的集合。每个实体都有一个对另一个实体的暂时引用。这种关系只是当前应用程序状态的一部分。这样,不会线程共享分离的实体引用吗?如果它在语义上是正确的,那么说一个实体现在是一个与另一个人聊天的人,你还会认为这是一个糟糕的设计吗? – 2013-05-03 20:14:56

+0

分离的实体只不过是一个普通的旧Java对象。相同的并发规则适用于其他任何其他对象。因此它与JPA没有任何关系,并且该属性是否短暂是无关紧要的。如果你有这样的设计,那么通常阅读并发性和线程安全性。不要在JPA中寻找答案,因为JPA在这种情况下无关紧要。 – 2013-05-03 20:21:11

+0

谢谢JB Nizet,非常感谢。然而,我不能同意一个分离的实体只不过是一个POJO而已。请参阅JPA 2.0规范,p。 79:“分离的实体实例[..]不再保证与数据库状态同步”。这个词是“保证”。 “Pro JPA 2”一书在第26页上说。 160:如果我们访问他的懒加载属性,“某些供应商可能试图解决分离实体之间的关系”。而EntityManager#merge的JavaDocs接受一个“实体实例”。实质上,你是对的。我想我只是指出了第三方的一些细微差别。 – 2013-05-03 20:44:36