首页 文章

如何在JPA中回滚事务?

提问于
浏览
4

我有一个由Spring框架维护的 EntityManager 对象,我使用 @PersistenceContext 注释将其注入到我想要的任何DAO类中 .

@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都使用通过 @PersistenceContext(unitName="entityManager") 注入的相同 EntityManager . 现在,如果在 setXYZ() 之后发生异常,那么我想回滚已保存的 XYZ 实体 . 但是,如何从中获得 EntityManager

如果所有的daos都拥有相同的对象,那么我可以只调用 EntityManager 类的 getTransaction().rollback() 方法吗? getTransaction() 是否返回新事务或当前与 EntityManager 关联的任何事务?

3 回答

  • 1
    • 如果您使用Spring AOP来管理事务,并且正确使用配置和注释,则默认效果是在发生运行时异常时将回滚事务 .

    • 如果您手动管理事务,则可以回滚事务,如下所示:

    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

  • 2

    一旦你从标记为@Transactional的方法抛出任何RuntimeException,它就会回滚:

    默认情况下,所有RuntimeExceptions回滚事务,其中检查的异常不:

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

    只是不要 grab 异常 . 让它冒泡 . 如果从事务方法调用抛出运行时异常,Spring将自动回滚事务 . 调用者至少会知道发生了一些不好的事情,而不是认为一切都很顺利 .

    无论如何,你的catch块可能不会捕获任何东西,因为大多数异常发生在刷新时,而flush主要发生在提交之前,在Spring事务拦截器中 . 请记住,持久化实体不会立即执行插入查询 . 它告诉Hibernate,在事务结束之前,必须执行一个插入 .

相关问题