[SPRING] @Transactional 내부의 try-catch에서 변경 사항을 커밋하십시오.
SPRING@Transactional 내부의 try-catch에서 변경 사항을 커밋하십시오.
내가 몇 가지 물건을하고 ActiveRecord 패턴 스타일에서 메커니즘을 로깅을 고려하십시오 :
@Transactional
public void doSmt() {
try {
someOperation(); // can throw exception
Logger.logIntoDb(); // if everything is OK
} catch {Exception e} {
Logger.logIntoDbWithException(e.getMessage()); // log error into db
throw new MyCustomException(e);
}
}
public static void logIntoDbWithException(String message) {
final LogEntry logEntry = new LogEntry();
logEntry.setDate(new Date());
logEntry.setMessage(message);
logEntry.persist();
}
실패의 경우 오류 메시지를 유지하고 싶지만 catch 절에서 예외를 다시 발생 시키려면 트랜잭션이 롤백되고 LogEntry는 유지되지 않습니다. 내가 보는 유일한 방법은 수동으로 flush ()를 persist () 이후에 호출하는 것이다.
이 작업을 수행하는 더 깨끗한 솔루션이 있습니까?
감사.
UPD :
나는 지속성을 수행하는 정적 메소드를 가지고 있기 때문에 받아 들인 대답에 다음과 같은 해킹을 적용해야합니다.
public static void logIntoDbWithException(String message) {
new Runnable() {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void run() {
final LogEntry logEntry = new LogEntry();
logEntry.setDate(new Date());
logEntry.setMessage(message);
logEntry.persist();
}
}.run();
}
해결법
-
==============================
1.첫째, flush ()를 호출해도 아무 것도 할 수 없습니다. flush ()는 아무 것도 저 지하지 않으며 동일한 트랜잭션에서 오류를 로깅 할 때 삽입이 롤백됩니다.
첫째, flush ()를 호출해도 아무 것도 할 수 없습니다. flush ()는 아무 것도 저 지하지 않으며 동일한 트랜잭션에서 오류를 로깅 할 때 삽입이 롤백됩니다.
따라서 오류를 기록하려면 새로운 '중첩 된'트랜잭션을 시작해야합니다.
public class A { @Autowired private B b; @Transactional public void doSmt() { try { someOperation(); // can throw exception b.logIntoDb(); // if everything is OK } catch {Exception e} { b.logIntoDbWithException(e.getMessage()); // log error into db throw new MyCustomException(e); } } } public class B{ //outer transaction is still active public void logIntoDb(String message) { final LogEntry logEntry = new LogEntry(); logEntry.setDate(new Date()); logEntry.setMessage(message); logEntry.persist(); } // 'outer' transaction will be suspended until this method completes // this new transaction will commit/rollback independently of the outer transaction @Transactional(propagation = Propagation.REQUIRES_NEW) public void logIntoDbWithException(String message) { final LogEntry logEntry = new LogEntry(); logEntry.setDate(new Date()); logEntry.setMessage(message); logEntry.persist(); } }
from https://stackoverflow.com/questions/36908407/commit-changes-in-try-catch-inside-transactional by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 테스트 및 메이븐 (0) | 2019.04.28 |
---|---|
[SPRING] 스프링 보안 - BcryptPasswordEncoder (0) | 2019.04.28 |
[SPRING] 스프링 부트 데이터와 MongoDB - 서브 디렉토리 배열 쿼리 필터링 (0) | 2019.04.28 |
[SPRING] OpenSessionInViewFilter를 사용할 때 'sessionFactory'라는 bean을 얻지 못했습니다. (0) | 2019.04.28 |
[SPRING] MultiActionController에서 Spring 유효성 검사를 수행하는 방법은 무엇입니까? (0) | 2019.04.28 |