【问题标题】:How do you auto-commit an SQL Server transaction in JPA?如何在 JPA 中自动提交 SQL Server 事务?
【发布时间】:2012-09-11 03:54:41
【问题描述】:

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

这不插入:

em.persist(this);

但这确实:

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

我猜我最初的参考点是this GWT doco

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

【问题讨论】:

    标签: sql-server hibernate jpa


    【解决方案1】:

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

    【讨论】:

    • link 有一个不使用事务的示例...您认为这是为什么?
    • 那是什么? Google AppEngine 使用 DataNucleus JPA,提供自动提交模式的 JPA 实现(正如我已经说过的)
    【解决方案2】:

    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>
    

    【讨论】:

      猜你喜欢
      • 2020-02-11
      • 1970-01-01
      • 2011-02-22
      • 1970-01-01
      • 1970-01-01
      • 2018-04-27
      • 2019-10-09
      • 2014-11-25
      • 2015-07-27
      相关资源
      最近更新 更多