복붙노트

[SPRING] 거기에 예외가 발생하지 않고 트랜잭션 롤백을 강제하는 방법이 있습니까?

SPRING

거기에 예외가 발생하지 않고 트랜잭션 롤백을 강제하는 방법이 있습니까?

나는 여러 가지 일을하는 방법을 가지고있다. 많은 사람들이 삽입과 업데이트를하고 있습니다. 그렇게 선언되었습니다 ...

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public int saveAll(){
 //do stuff;
}

그것이 예상했던 것과 똑같이 작동하며 문제가 없습니다. 그러나 예외가 발생하지 않았지만 롤백을 강요하고 싶을 때가 있습니다 ... 상황에 따라 적절한 조건을 만났을 때 예외가 발생하지만 추한 것이고 나는 그것을 좋아하지 않습니다.

어떻게 든 롤백을 적극적으로 호출 할 수 있습니까? 예외는 그것을 부른다. .. 나는 아마 내가 할 수 있다고 생각하고있다.

해결법

  1. ==============================

    1.Spring Transactions에서는 TransactionStatus.setRollbackOnly ()를 사용합니다.

    Spring Transactions에서는 TransactionStatus.setRollbackOnly ()를 사용합니다.

    여기서 문제는 거래를 구분하기 위해 @Transactional을 사용한다는 것입니다. 이것은 비 침입적인 이점이 있지만 트랜잭션 컨텍스트와 수동으로 상호 작용하려는 경우에는 불가능합니다.

    트랜잭션 상태를 엄격하게 제어하려면 선언적 주석이 아닌 프로그래밍 방식 트랜잭션을 사용해야합니다. 이것은 Spring의 TransactionTemplate을 사용하거나 PlatformTransactionManager를 직접 사용하는 것을 의미합니다. Spring 참조 매뉴얼의 9.6 절을 보라.

    TransactionTemplate을 사용하면 TransactionCallback을 구현하는 콜백 객체를 제공하고이 콜백의 코드는 TransactionStatus 객체에 액세스 할 수 있습니다.

    @Transactional만큼 좋지는 않지만, 당신은 당신의 tx 상태를보다 잘 제어 할 수 있습니다.

  2. ==============================

    2.우리는 EJB를 사용하지 않지만 단순한 Spring과 AOP 방식을 선택했습니다. 우리는 새로운 주석 @TransactionalWithRollback을 구현하고 AOP를 사용하여 주석이 달린 메서드를 "around"advice로 둘러 쌉니다. 조언을 구현하기 위해 앞서 언급 한 TransactionTemplate을 사용합니다. 이것은 초기에 약간의 작업을 의미하지만 결과적으로 @TransactionalWithRollback으로 메소드에 주석을 달 수 있습니다. 다른 경우에는 @Transactional을 사용하는 것과 같습니다. 주 코드는 깨끗하고 단순 해 보입니다.

    우리는 EJB를 사용하지 않지만 단순한 Spring과 AOP 방식을 선택했습니다. 우리는 새로운 주석 @TransactionalWithRollback을 구현하고 AOP를 사용하여 주석이 달린 메서드를 "around"advice로 둘러 쌉니다. 조언을 구현하기 위해 앞서 언급 한 TransactionTemplate을 사용합니다. 이것은 초기에 약간의 작업을 의미하지만 결과적으로 @TransactionalWithRollback으로 메소드에 주석을 달 수 있습니다. 다른 경우에는 @Transactional을 사용하는 것과 같습니다. 주 코드는 깨끗하고 단순 해 보입니다.

    //
    // Service class - looks nice
    //
    class MyServiceImpl implements MyService {
        @TransactionalWithRollback
        public int serviceMethod {
            // DO "read only" WORK
        }
    }
    
    //
    // Annotation definition
    //
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public @interface TransactionalWithRollback {
    }
    
    //
    // the around advice implementation
    //
    public class TransactionalWithRollbackInterceptor {
        private TransactionTemplate txTemplate;
        @Autowired private void setTransactionManager(PlatformTransactionManager txMan) {
            txTemplate = new TransactionTemplate(txMan);
        }
    
        public Object doInTransactionWithRollback(final ProceedingJoinPoint pjp) throws Throwable {
            return txTemplate.execute(new TransactionCallback<Object>() {
                @Override public Object doInTransaction(TransactionStatus status) {
                    status.setRollbackOnly();
                    try {
                        return pjp.proceed();
                    } catch(RuntimeException e) {
                        throw e;
                    } catch (Throwable e) {
                        throw new RuntimeException(e);
                    }
                }
            });
        }
    }
    
    //
    // snippet from applicationContext.xml:
    //
    <bean id="txWithRollbackInterceptor" class="net.gmc.planner.aop.TransactionalWithRollbackInterceptor" />
    
    <aop:config>
        <aop:aspect id="txWithRollbackAspect" ref="txWithRollbackInterceptor">
            <aop:pointcut 
                id="servicesWithTxWithRollbackAnnotation" 
                expression="execution( * org.projectx..*.*(..) ) and @annotation(org.projectx.aop.TransactionalWithRollback)"/>
            <aop:around method="doInTransactionWithRollback" pointcut-ref="servicesWithTxWithRollbackAnnotation"/>
        </aop:aspect>
    </aop:config>
    
  3. ==============================

    3.EJB에 있다면 SessionContext에서 setRollbackOnly ()를 호출하십시오.

    EJB에 있다면 SessionContext에서 setRollbackOnly ()를 호출하십시오.

    다음과 같이 SessionContext를 삽입 할 수 있습니다.

    public MyClass {
        @Resource
        private SessionContext sessionContext;
    
        @Transactional(propagation = Propagation.REQUIRED, 
                       isolation = Isolation.DEFAULT, 
                       readOnly = false)
        public int saveAll(){
            //do stuff;
            if(oops == true) {
                 sessionContext.setRollbackOnly();
                 return;
            }
        }
    

    setRollbackOnly ()는 EJBContext의 멤버입니다. SessionContext는 EJBContext를 확장합니다. http://java.sun.com/j2ee/1.4/docs/api/javax/ejb/SessionContext.html 세션 EJB에서만 사용할 수 있습니다.

    @Resource는 표준 Java EE 주석이므로 Eclipse에서 설정을 확인해야합니다. @Resource를 사용하여 SessionContext를 삽입하는 방법의 예가있다.

    Eclipse에서 @Resource를 찾지 못하는 이유를 설명하는 EJB를 사용하지 않는 것처럼 보일 수 있으므로 이것이 아마도 여러분의 해결책이 아닌 것 같습니다.

    그렇다면 거래와 직접 상호 작용해야합니다 (거래 템플릿 참조).

  4. ==============================

    4.이 작품은 나를 위해 :

    이 작품은 나를 위해 :

    TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
    
  5. ==============================

    5.트랜잭션 관리자를 Spring에 삽입해야한다. 그런 다음 롤백 메서드를 호출하면됩니다.

    트랜잭션 관리자를 Spring에 삽입해야한다. 그런 다음 롤백 메서드를 호출하면됩니다.

  6. ==============================

    6.@Transactional 주석이 붙은 서비스 메소드가 있습니다. 유효성 검사가 실패하고 현재 작업 단위에 첨부 된 엔티티가있는 경우 sessionFactory.getCurrentSession (). evict (entity)를 사용하여 데이터베이스에 아무 것도 기록되지 않도록합니다. 그렇게하면 예외를 throw 할 필요가 없습니다.

    @Transactional 주석이 붙은 서비스 메소드가 있습니다. 유효성 검사가 실패하고 현재 작업 단위에 첨부 된 엔티티가있는 경우 sessionFactory.getCurrentSession (). evict (entity)를 사용하여 데이터베이스에 아무 것도 기록되지 않도록합니다. 그렇게하면 예외를 throw 할 필요가 없습니다.

  7. ==============================

    7.예, 예외가 발생하지 않고 @Transactional (클래스 수준)을 사용하면서 롤백을 강제 실행할 수 있습니다. 우리는 단순히 예외 (어떤 적합한 것)를 던질 수 있습니다. 처럼

    예, 예외가 발생하지 않고 @Transactional (클래스 수준)을 사용하면서 롤백을 강제 실행할 수 있습니다. 우리는 단순히 예외 (어떤 적합한 것)를 던질 수 있습니다. 처럼

    if(some condition matches){
     throw new DataIntegrityViolationException("Rollback Tnx.. Since ..." );
    } 
    
  8. ==============================

    8.예외를 던집니다. 프레임 워크를 설계대로 사용하십시오. 그렇지 않으면 선언적 트랜잭션 관리를 사용하지 말고 위의 skaffman 권고를 따르십시오. 그것을 간단하게하십시오.

    예외를 던집니다. 프레임 워크를 설계대로 사용하십시오. 그렇지 않으면 선언적 트랜잭션 관리를 사용하지 말고 위의 skaffman 권고를 따르십시오. 그것을 간단하게하십시오.

  9. from https://stackoverflow.com/questions/832375/is-there-a-way-to-force-a-transactional-rollback-without-encountering-an-excepti by cc-by-sa and MIT license