@Transactional 주석. 롤백하는 방법?
이 주석을 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();
}
}
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);
}
}
다음은 주석이 잘 작동하는 테스트입니다.
@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>
감사합니다. 러시아는 당신을 잊지 않을 것입니다!
으로 RuntimeException
표시된 메소드에서 아무거나 던지십시오 @Transactional
.
By default all RuntimeException
s rollback transaction whereas checked exceptions don't. This is an EJB legacy. You can configure this by using rollbackFor()
and noRollbackFor()
annotation parameters:
@Transactional(rollbackFor=Exception.class)
This will rollback transaction after throwing any exception.
or programatically
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
You can throw an unchecked exception from the method which you wish to roll back. This will be detected by spring and your transaction will be marked as rollback only.
I'm assuming you're using Spring here. And I assume the annotations you refer to in your tests are the spring test based annotations.
The recommended way to indicate to the Spring Framework's transaction infrastructure that a transaction's work is to be rolled back is to throw an Exception from code that is currently executing in the context of a transaction.
and note that:
please note that the Spring Framework's transaction infrastructure code will, by default, only mark a transaction for rollback in the case of runtime, unchecked exceptions; that is, when the thrown exception is an instance or subclass of RuntimeException.
For me rollbackFor was not enough, so I had to put this and it works as expected:
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
I hope it helps :-)
참고URL : https://stackoverflow.com/questions/7872773/annotation-transactional-how-to-rollback
'program story' 카테고리의 다른 글
배열 또는 목록이 기본적으로 C #에서 참조로 전달됩니까? (0) | 2020.10.18 |
---|---|
PostgreSQL : 명령 줄에서 매개 변수를 전달하는 방법은 무엇입니까? (0) | 2020.10.18 |
리스트 이해는 루프 변수에 쓰지만 생성기는 쓰지 않는 이유는 무엇입니까? (0) | 2020.10.17 |
C ++ 11의 std :: atomic :: compare_exchange_weak () 이해 (0) | 2020.10.17 |
Rust는 가비지 수집기 대신 무엇을 가지고 있습니까? (0) | 2020.10.17 |