1

为什么我需要使用事务来持久化实体?有什么我可以添加到我的 persistence.xml 以自动提交的吗?

这不会插入:

em.persist(this);

但这确实:

em.getTransaction().begin();
em.persist(this);
em.getTransaction().commit();

我想我最初的参考点是这个 GWT doco

public void persist() 
{
   EntityManager em = entityManager();
   try 
   {
     em.persist(this);
   } 
   finally 
   {
     em.close();    
   }  
}
4

2 回答 2

1

IMO 在 persistence.xml 中没有这样的设置

我认为这种模式是从 JDBC 事务管理中采用的,您可以在连接上设置 autocommit false,然后执行任意数量的查询。但是除非您在连接上调用提交,否则不会提交事务。如果 autocommit 为 false(这是默认值),则每个执行的语句都被隐式提交,如果我们有多个语句需要在原子操作中运行,我们不希望这种情况发生。

以您的示例为例,当您持久化对象时,该对象可能具有脏的关联并且也需要持久化。所以会有不止一个 sql 需要以原子方式运行。所以使用了上面提到的事务管理策略。

实体管理器(在 JPA 中)和会话 API(在 Hibernate 中)旨在抽象数据库上的 CRUD 操作。为了实际提交生成的 sql 语句,事务 API 被设计为对事务管理的抽象。我认为这种单独抽象的原因是事务通常有两种类型——资源本地事务和分布式事务。

事务管理基础架构需要以不同于分布式事务的方式处理资源本地事务。在资源本地事务中,发送到数据库的所有 sql 在连接上调用提交时由数据库提交,或者在连接上调用回滚时回滚。在分布式事务管理中,事务管理器组件是管理向所有参与者提交或回滚信号的组件。

在 JPA 中,您可以将事务类型称为

<persistence-unit transaction-type="RESOURCE_LOCAL  or JTA">
 .................................
</persitence-unit>
于 2012-09-11T04:28:29.670 回答
1

JPA 没有定义此类行为;根据规范,任何“persist()”都被定义为等待下一个事务。显然,JPA 的某些实现(例如DataNucleus JPA)确实提供了该(自动提交)设施,但它超出了(不是)JPA 规范的一部分

于 2012-09-11T06:29:29.163 回答