OpenJPA事务 - 单个实体管理器还是多个实体管理器?

3
我有一个DBManager单例,确保只实例化一个EntityManagerFactory。 我正在考虑使用单个或多个EntityManager,因为每个EntityManager仅与一个事务相关联。
我需要使用多个事务。 JPA不支持嵌套事务。
所以我的问题是:在大多数使用单个数据库环境中使用事务的普通应用程序中,您是否根本不使用单个EntityManager? 到目前为止,我一直在使用多个EntityManager,但希望看到创建单个EntityManager是否可以解决问题并加快速度。
所以我发现以下内容很有帮助:希望对其他人也有所帮助。 http://en.wikibooks.org/wiki/Java_Persistence/Transactions#Nested_Transactions 在JPA中,从创建EntityManager开始,它就处于事务中。因此,begin方法有些多余。在调用begin之前,某些操作(如persist、merge、remove)是无法执行的。可以执行查询,并且可以更改查询到的对象,尽管在JPA规范中对这些更改会发生什么有些不确定,但通常它们将被提交。但最好在更改对象之前调用begin。通常最好为每个事务创建一个新的EntityManager,以避免持久化上下文中残留过时的对象,并允许以前管理的对象进行垃圾回收。
成功提交后,EntityManager仍然可以继续使用,并且所有受管理的对象仍然受管理。但通常最好关闭或清除EntityManager,以允许垃圾回收并避免过时数据。如果提交失败,则认为受管理的对象已分离,并清除EntityManager。这意味着无法捕获和重试提交失败,如果出现错误,则必须重新执行整个事务。先前管理的对象还可能处于不一致状态,这意味着某些对象锁定版本可能已增加。如果事务已标记为回滚,则提交也将失败。这既可以通过调用setRollbackOnly显式设置,也可以在任何查询或查找操作失败时设置。这可能是一个问题,因为某些查询可能会失败,但不希望导致整个事务回滚。
回滚操作将仅回滚数据库事务。持久化上下文中的受管理对象将变为分离状态,并清除EntityManager。这意味着以前读取的任何对象都不应再使用,并且不再是持久化上下文的一部分。对对象所做的更改将保留为原样,对象更改将不会被还原。
1个回答

3

EntityManager 根据定义不是线程安全的。因此,除非您的应用程序是单线程的,否则使用单个EM可能不是最佳选择。


一个基于CLI的应用程序是单线程的,假设你没有调用任何Thread.start()方法,这是正确的吗? - thirdy
如果一个应用程序需要在ajax中使用懒加载,但也需要合并对这些懒加载实体所做的更改,那么应该怎么办呢? - Askar Kalykov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接