注释@Transactional。 如何回滚?
我成功地将这个注解用于了Dao类。 回滚适用于testing。
但是现在我需要回滚实际的代码,而不仅仅是testing。 有特殊的注释用于testing。 但是哪些注释是针对非testing代码的? 这对我来说是一个很大的问题。 我已经花了一天的时间了。 官方文件不符合我的需要。
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(); } }
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); } }
这是一个testing,注释工作得很好:
@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)); }
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> ...
**是的,我回滚了交易。 我刚刚添加了BEAN的服务…然后注释@Transactional开始工作:-) **
<bean id="service" class="main.MyClass"> <property name="employeeDao" ref="employeeDao" /> </bean>
谢谢大家,俄罗斯不会忘记你!
只需从标记为@Transactional
的方法中引发任何RuntimeException
。
默认情况下,所有RuntimeException
的回滚事务,而检查的exception不会。 这是一个EJB的遗产。 您可以使用rollbackFor()
和noRollbackFor()
注释参数来configuration它:
@Transactional(rollbackFor=Exception.class)
这将抛出任何exception后回滚事务。
或编程
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
您可以从您希望回滚的方法中抛出未经检查的exception。 这将在春季检测到,您的交易将被标记为仅回滚。
我假设你在这里使用Spring。 我假设你在testing中引用的注释是基于春季testing的注释。
向Spring框架的事务基础结构指示事务的工作将被回滚的推荐方法是从事务上下文中正在执行的代码中引发一个exception。
并注意到:
请注意,Spring框架的事务基础架构代码默认情况下只会在运行时标记事务回滚,而不会检查exception; 也就是说,抛出的exception是RuntimeException的一个实例或子类。
如果你想在你的API中创build一个Rollback()方法,可能有办法。 创build一个新的方法()。
@Component public class MyDBApiImpl implements MyDBApi{ @Autowired private DummyExceptionLauncher dummyExceptionLauncher; @Override @Transactional(propagation=Propagation.MANDATORY) public void rollback(){ try{ dummyExceptionLauncher.throwException(); }catch(RuntimeException ex){ log.debug("Transaction deliberately aborted"); } } }
哪里
@Component public class DummyExceptionLauncherImpl implements DummyExceptionLauncher{ @Override @Transactional(propagation=Propagation.MANDATORY) public void throwException(){ throw new RuntimeException("Exception deliberated thrown to abort exception"); } }
请注意,您可能需要捕获回滚exception“标记为rollbackOnly的事务”。