[java] @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.

기본적으로 모든 RuntimeException롤백 트랜잭션이 있지만 확인 된 예외는 그렇지 않습니다. 이것은 EJB 레거시입니다. rollbackFor()noRollbackFor()주석 매개 변수 를 사용하여이를 구성 할 수 있습니다 .

@Transactional(rollbackFor=Exception.class)

이 던지는 후 트랜잭션을 롤백합니다 모든 예외를.


답변

또는 프로그래밍 방식으로

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();


답변

롤백하려는 메서드에서 확인되지 않은 예외를 throw 할 수 있습니다. 이것은 봄에 감지되며 귀하의 거래는 롤백으로 만 표시됩니다.

여기서 Spring을 사용하고 있다고 가정합니다. 그리고 테스트에서 참조하는 주석이 스프링 테스트 기반 주석이라고 가정합니다.

트랜잭션의 작업이 롤백 될 것임을 Spring Framework의 트랜잭션 인프라에 표시하는 권장 방법은 트랜잭션 컨텍스트에서 현재 실행중인 코드에서 예외를 발생시키는 것입니다.

다음 사항에 유의하십시오.

Spring Framework의 트랜잭션 인프라 코드는 기본적으로 런타임, 확인되지 않은 예외의 경우에만 트랜잭션을 롤백하도록 표시합니다. 즉, throw 된 예외가 RuntimeException의 인스턴스 또는 하위 클래스 인 경우입니다.


답변

나를 위해 rollbackFor는 충분하지 않았으므로 이것을 넣어야했고 예상대로 작동합니다.

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)

나는 그것이 도움이되기를 바랍니다 🙂


답변