注释@Transactional.如何回滚?

Mos*_*Boy 78 java spring hibernate

我成功地为Dao类使用了这个注释.并且回滚适用于测试.

但现在我需要回滚实际代码,而不仅仅是测试.在测试中使用特殊注释.但是哪些注释适用于非测试代码?这对我来说是个大问题.我已经花了一天时间.官方文件不符合我的需要.

class MyClass { // this does not make rollback! And record appears in DB.
        EmployeeDaoInterface employeeDao;

        public MyClass() {
            ApplicationContext context = new ClassPathXmlApplicationContext(
                    new String[] { "HibernateDaoBeans.xml" });
            employeeDao = (IEmployeeDao) context.getBean("employeeDao");
         }

        @Transactional(rollbackFor={Exception.class})
    public void doInsert( Employee newEmp ) throws Exception {
        employeeDao.insertEmployee(newEmp);
        throw new RuntimeException();
    }
}
Run Code Online (Sandbox Code Playgroud)

employeeDao是

@Transactional
public class EmployeeDao implements IEmployeeDao {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public void insertEmployee(Employee emp) {
        sessionFactory.getCurrentSession().save(emp);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个注释适用的测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/HibernateDaoBeans.xml" })
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)
@Transactional
public class EmployeeDaoTest {

    @Autowired
    EmployeeDaoInterface empDao;

    @Test
    public void insert_record() {
       ...
       assertTrue(empDao.insertEmployee(newEmp));
    }
Run Code Online (Sandbox Code Playgroud)

HibernateDaoBeans.xml

   ...
<bean id="employeeDao" class="Hibernate.EmployeeDao">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
    <tx:annotation-driven transaction-manager="txManager"/>

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>
   ...
Run Code Online (Sandbox Code Playgroud)


**是的,我回滚了这笔交易.我刚刚为服务添加了BEAN ...然后注释@Transactional开始工作:-)**

<bean id="service" class="main.MyClass">
    <property name="employeeDao" ref="employeeDao" />
</bean>
Run Code Online (Sandbox Code Playgroud)

谢谢大家,俄罗斯不会忘记你!

Tom*_*icz 137

只需RuntimeException从标记为的方法中抛出任何内容@Transactional.

默认情况下,所有RuntimeExceptions回滚事务,而已检查的异常则不.这是EJB的遗产.您可以使用rollbackFor()noRollbackFor()注释参数进行配置:

@Transactional(rollbackFor=Exception.class)
Run Code Online (Sandbox Code Playgroud)

抛出任何异常后,这将回滚事务.

  • 它真的有这样的方式:-).如果您有一个服务调用几个DAO,该服务也需要一个`@Transactional`注释.否则,在服务中抛出异常之前,每个DAO调用都会启动并提交新事务.底线是:例外必须保留(转义)标记为`@Transactional`的方法. (3认同)

Ste*_* K. 66

或以编程方式

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
Run Code Online (Sandbox Code Playgroud)

  • 是.因为有时您需要回滚而不会抛出错误. (8认同)
  • 你是一个救星. (2认同)
  • 有时它不起作用。例如,就我而言,我有一个事务性服务和非事务性存储库。我从服务调用存储库,因此,它应该参与由服务打开的事务。但是,如果我从我的非事务性存储库中调用您的代码,尽管存在事务,它仍会抛出 NoTransactionException。 (2认同)
  • 您想在“非事务性存储库”中回滚哪个事务? (2认同)

Ale*_*nes 5

您可以从要回滚的方法中引发未经检查的异常。春季将检测到此情况,并且您的交易记录将仅标记为回滚。

我假设您在这里使用Spring。我假设您在测试中引用的注释是基于Spring测试的注释。

向Spring框架的事务基础结构指示要回滚事务的建议方法是从事务上下文中当前正在执行的代码中引发Exception。

并注意:

请注意,默认情况下,Spring Framework的事务基础结构代码仅在运行时未检查的异常的情况下才将事务标记为回滚;也就是说,当抛出的异常是RuntimeException的实例或子类时。