예외 없이 트랜잭션 롤백을 수행하시겠습니까?
여러 가지 작업을 수행하는 방법이 있습니다. 그 중에서도 여러 개의 삽입과 업데이트를 수행합니다.
다음과 같이 선언됩니다.
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
public int saveAll() {
//do stuff;
}
그것은 정확히 원래대로 작동하고 저는 문제가 없습니다.하지만 예외가 없음에도 불구하고 롤백을 강제로 실행하고 싶을 때가 있습니다.지금은 조건이 맞으면 무조건 예외를 강요하고 있지만, 보기 흉하고 마음에 안 들어요.
어떻게든 롤백을 적극적으로 호출할 수 있습니까?
예외적으로...저도 할 수 있을 것 같아요.
스링트랜션서다사용다니합음을에잭프다사를 합니다.TransactionStatus.setRollbackOnly()
.
여기서 문제는 당신이 사용하고 있다는 것입니다.@Transactional
사용자의 트랜잭션을 구분합니다.이것은 비침습적이라는 이점이 있지만, 트랜잭션 컨텍스트와 수동으로 상호 작용하려면 할 수 없다는 것을 의미하기도 합니다.
트랜잭션 상태를 엄격하게 제어하려면 선언적 주석 대신 프로그래밍 방식의 트랜잭션을 사용해야 합니다.즉, Spring's Transaction을 사용합니다.템플릿을 작성하거나 플랫폼 트랜잭션 관리자를 직접 사용합니다.스프링 참조 매뉴얼의 섹션 9.6을 참조하십시오.
와 함께TransactionTemplate
은 다을구현콜개제공다니합체를 합니다.TransactionCallback
이 는 그고이콜코액수할있다습니세스드는리백의▁▁to▁in에 접속할 수 .TransactionStatus
물건들.
다 좋지 않습니다@Transactional
하지만 당신은 당신의 tx 상태를 더 가까이 통제할 수 있습니다.
이것은 나에게 도움이 됩니다.
TransactionInterceptor.currentTransactionStatus().setRollbackOnly();
우리는 EJB를 사용하지 않고, 단순한 Spring과 AOP 접근 방식을 선택했습니다.새로운 을 구현했습니다.@TransactionalWithRollback
그리고 AOP를 사용하여 주석이 달린 방법을 "주변" 조언으로 포장했습니다.하는 것은 다음과 같습니다.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>
러setRollbackOnly()
에서.SessionContext
EJB에 있는 경우.
주사를 놓을 수 .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()
다멤다 ▁is의▁of▁member.EJBContext
.SessionContext
확된장EJBContext
http://java.sun.com/j2ee/1.4/docs/api/javax/ejb/SessionContext.html 세션 EJB에서만 사용할 수 있습니다.
@Resource
는 표준 Java EE 주석이므로 Eclipse에서 설정을 확인해야 합니다.다음은 다음을 사용하여 세션 컨텍스트를 주입하는 방법의 예입니다.@Resource
.
EJB와 함께 작업하지 않을 수도 있기 때문에 이클립스가 발견하지 못하는 이유를 설명하는 것은 아마도 당신의 해결책이 아닐 것입니다.@Resource
.
그런 경우에는 트랜잭션과 직접 상호 작용해야 합니다. 트랜잭션 템플릿을 참조하십시오.
당신은 봄에 거래 관리자를 투입해야 합니다.그러면 롤백 방법을 호출하면 됩니다.
다음과 같은 주석이 달린 서비스 방법이 있습니다.@Transactional
유효성 검사에 실패하고 현재 작업 단위에 이미 연결된 엔티티가 있는 경우 사용sessionFactory.getCurrentSession().evict(entity)
데이터베이스에 기록된 내용이 없는지 확인합니다.그래야 제가 예외를 둘 필요가 없습니다.
지금은 적당한 조건에 부딪히면 무조건 예외를 강요하고 있지만, 보기 흉하고 마음에 들지 않습니다.
왜 못생겼어요?저는 그렇지 않다고 주장할 것입니다.당신은 당신의 것을 가지고 있습니다.@Transactional
당신의 공개적인 방법으로.rollbackFor
이와 같은 속성:
@Transactional(rollbackFor = Exception.class)
public void myMethod() throws IllegalStateException {
그런 다음 메소드가 남쪽으로 이동하면 표준 Java 예외가 발생합니다. 아마도 다음과 같습니다.
throw new IllegalStateException("XXX");
이것은 아름답습니다. 기존의 표준 Java 예외를 1-라이너만 사용하여 사용하면 프레임워크가 롤백을 수행합니다. 이것으로 끝입니다.
예외를 적용하고 프레임워크를 설계된 대로 사용합니다. 그렇지 않으면 선언적 트랜잭션 관리를 사용하지 말고 위의 직원 조언을 따르십시오.단순하게 받아들여라.
언급URL : https://stackoverflow.com/questions/832375/force-a-transactional-rollback-without-encountering-an-exception
'programing' 카테고리의 다른 글
노드의 child_process를 약속하는 방법.exec 및 child_process.Bluebird에서 execFile 기능을 사용하시겠습니까? (0) | 2023.07.26 |
---|---|
오류: '노드'에서 'appendChild'를 실행하지 못했습니다. 매개 변수 1이 '노드' 유형이 아닙니다. (0) | 2023.07.26 |
Python 개체에 대한 복사/딥 복사 작업을 재정의하는 방법은 무엇입니까? (0) | 2023.07.26 |
정의되지 않은 메트릭 경고: F-점수가 잘못 정의되었으며 예측된 샘플이 없는 레이블에서 0.0으로 설정되었습니다. (0) | 2023.07.26 |
활성화 가능 여부구성 요소가 없는 경로로 자식을 활성화할 수 있음 (0) | 2023.07.26 |