2014-10-05 183 views
2

我有Spring框架保持着EntityManager对象,我在任何DAO类我想用@PersistenceContext注解这样注入它..如何在JPA中回滚事务?

@PersistenceContext(unitName="entityManager") 
private EntityManager em; 

我使用这些DAO类在数据库中像这样保存..

class MyClass 
{ 
    @Resource(name="myDao") 
    private MyDao dao; 

    @Resource(name="myAnotherDao") 
    private MyAnotherDao anotherDao; 

    public void save(String s1,String s2) 
    { 
     try 
     { 
      MyEntity m=new MyEntity(); 
      m.setName(s1); 
      // .. and so on .. 

      XYZ x=new XYZ(); 
      x.setDEF(s2); 

      anotherDao.save(x); 

      m.setXYZ(x); 
      // .. some other stuff .. // 
      dao.saveEntity(m); 
     } 
     catch(Exception e) 
     { 
      // I would like to rollback the transaction 
     } 
    } 
} 

现在,无论是这里的DAOS使用相同的EntityManager通过@PersistenceContext(unitName="entityManager")注入。现在,如果在setXYZ()之后发生异常,那么我想回滚即使保存的实体XYZ。但是,如何从中获得EntityManager

如果所有道数都保持相同的对象,那么我可以只调用EntityManager类的getTransaction().rollback()方法吗? getTransaction()是否会返回一个新的交易或任何当前与EntityManager相关联的交易?

回答

0

只是没有发现异常。让它泡沫。如果从事务性方法调用中抛出运行时异常,Spring将自动回滚事务。而且来电者至少会知道发生了一些不好的事情,而不是认为一切都很顺利。

无论如何,你的catch块可能不会捕获任何东西,因为大部分异常发生在flush时间,并且flush主要发生在commit事务之前,在Spring事务拦截器中。记住,坚持一个实体不会立即执行插入查询。它只是告诉Hibernate,在事务结束之前,必须执行插入操作。

+0

但在上述例子中,XYZ实体被保存,如果它即保存后出现异常,同时节省了myEntity所随后, XYZ实体保存是否回滚?这正是我想要的。 – user12458 2014-10-05 07:22:37

+0

当然。这是交易的定义。它可以提交,并且在事务内部执行的所有插入,更新和删除都成功,或者它将回滚,并且在事务内部执行的所有插入,更新和删除都将被取消。 – 2014-10-05 07:25:09

+0

现在,在我的情况下,我实际上为EntityManager使用了相同的'unitName',我可以说XYZ和MyEntity都保存在同一个事务中吗? – user12458 2014-10-05 07:26:35

3
  1. 如果使用Spring AOP的管理事务,配置和注释使用权,默认的效果是当运行时异常发生的交易将被回滚。

  2. 如果交易手动管理,你可以这样回滚事务:

    EntityManager em = createEntityManager(); 
    
    try { 
    
        em.getTransaction().begin(); 
        // Do something with the EntityManager such as persist(), merge() or remove() 
        em.getTransaction().commit(); 
    } catch(Exception e) { 
    
        em.getTransaction().rollback(); 
    } 
    
    em.close(); 
    

多见于: http://en.wikibooks.org/wiki/Java_Persistence/Transactions http://www.developerscrappad.com/547/java/java-ee/ejb3-x-jpa-when-to-use-rollback-and-setrollbackonly/#sthash.jx3XlK5m.dpuf

0

一旦你抛出任何的RuntimeException将回滚从标记为@Transactional的方法如下:

默认情况下,所有RuntimeExceptions ROLLBACK TRANSACTION其中作为托运例外不会:

@Transactional(rollbackFor={MyRuntimeException.class, AnotherRuntimeException.class}) 
public SomeVal someTransactionalMethod(){ 
    ... 
}