Table of Contents
Transactional 과 Exception 그리고 로그 저장
예외가 발생했을 때 로그를 저장하고 예외를 발생시키려 한다.
하지만 로그가 저장이 되지 않는다.
예제
정상적으로 실행되고 로그가 저장될 것처럼 보이지만 로그는 저장되지 않는다.
Transactional
에 의해 DB 저장이 롤복되기 때문이다.
@Transactional
public LoginResponse login(LoginRequest request, String ipAddress, String userAgent) {
String email = request.getEmail();
Optional<User> userOptional = userRepository.findByEmail(email);
if (userOptional.isEmpty()) {
loginLogService.logFailedLogin(email, ipAddress, userAgent, "존재하지 않는 이메일");
throw new LoginFailedException("이메일 또는 비밀번호가 올바르지 않습니다.");
}
// ......
}
@Transactional
public void logFailedLogin(String email, String ipAddress, String userAgent, String failureReason) {
LoginLog loginLog = LoginLog.builder()
.email(email)
.ipAddress(ipAddress)
.userAgent(userAgent)
.status(LoginLog.LoginStatus.FAILURE)
.failureReason(failureReason)
.build();
loginLogRepository.save(loginLog);
log.warn("Failed login logged for email: {}, IP: {}, Reason: {}", email, ipAddress, failureReason);
}
해결
REQUIRES_NEW
를 이용해 아예 별도의 DB 연결로 분리해 주어야 한다.
다만 별도의 DB 연결이 된다는 의미는 한개의 DB 연결이 아니라 두개의 DB 연결을 필요로 한다는 의미가 된다.
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void logFailedLogin(String email, String ipAddress, String userAgent, String failureReason) {
// ......
}