해결된 질문
작성
·
53
0
질문1:
강의에서 saveChatMessage() 메소드 진입시
@Transactional(transactionManager = "createChatTransacationMansger")
사용하는것을 말씀 해주셨는데요. 선생님께서 말씀해주신 강의 내용을 그대로 말씀드리자면
"
웹소켓 같은 경우에는 하나의 커넥션 즉 세션을 하나에 계속 공유하고 계속 사용 중이기 때문에
이 스톰프를 사용하는 웹소켓 통신 아니면 기본적인 웹소켓 통신에서도 이 트랜잭션에 대한 경계가 되게 명확하지가 않는 경우가 있습니다.
"
즉 이 말씀은 따로 이렇게
@Transactional
public void saveChatMessage(Message msg) {
chatRepository.save(chat);
}
@TransactionManager() 만 추가해서 관리 하면 문제가 생기고
@Transactional(transactionManager = "createChatTransacationMansger")
이렇게 별도로 TransactionManager 를 추가해서 관리 해야 문제가 없다고 이해 하면 될까요???
왜 TransactionManager 를 따로 만들어서 관리하는지 이해가 안가네요 ㅠ,ㅠ
그리고
"웹소켓 같은 경우에는 하나의 커넥션 즉 세션을 하나에 계속 공유하고 계속 사용 중이기 때문에 이 스톰프를 사용하는 웹소켓 통신 아니면 기본적인 웹소켓 통신에서도 이 트랜잭션에 대한 경계가 되게 명확하지가 않는 경우가 있습니다"
즉 이 말씀은 saveChatMessage 경우는 웹소켓 전용만 사용 할때만 이용하는 오퍼레이션 이기 때문에
다른 HTTP 통신 경우에 오는 FLOW 경우는 saveChatMessage() 메소드는 사용하지 마라 라는 의미로
@Transactional(transactionManager = "createChatTransacationMansger")
이렇게 별도의 TransactionManager을 사용한 것인지 궁금 합니다.
질문2
선생님이 말씀해주신 내용을 그대로 말씀드리자면
플러시는 기본적으로 JPA에서 다루고자 하는 트랜잭션이 담겨있어야 되는데 담겨있지 않았다는 에러가 발생하게 될 거예요
왜냐하면 제가 말씀드렸던 것처럼 웹소켓은 하나의 통신으로만 공유를 하기 때문에 경계가 명확하지 않아서
JPA 에서 일반적으로 트랜지액션을 잘 인식을 하지 못하고 잘 넣어주지를 못합니다
이렇게 트랜젝션을 선언하지 않으면 문제가 발생된다고 해주셨는데요.
@Transactional
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must not be null");
if (this.entityInformation.isNew(entity)) {
this.entityManager.persist(entity);
return entity;
} else {
return this.entityManager.merge(entity);
}
}
JPA save 메소드를 보면 이렇게 @Transaction 을 선언하기 때문에 굳이 @Transaction 을 선언하지 않아도 문제가 없지 않을까요??
답변 2
0
음 이 부분은 아마 직접 해보시면 이해가 되실겁니다.
물론 매니저에 대한 어노테이션을 사용하시지 않으셔도 됩니다.
제가 말씀드리고 싶은 부분은 해당 프로젝트에서는 MySQL에 대한 Transaction격리 수준을 제어하는 Config 파일을 작성을 하였어요.
이렇게 작성이 되면, Spring에서 자동으로 Transaction을 관리해주지 않습니다.
그래서 안정적인 운영을 위해서 Jpa나 DB를 조회하는 부분에 대해서 Manager 어노테이션을 붙여주셔야 합니다.
여기서 그냥 일반 Transaction을 사용하셔도 되고 Manager을 사용하셔도 됩니다.
그런데 그냥 코드의 통일상 Manager를 사용하시는걸 추천드리는 겁니다.
아마 가장 쉬운 이해는 직접 어노테이션이 없는 상황에서 적용을 해보셨을 때, DB에 데이터가 제대로 들어가는지 확인해 보시면 될 꺼같습니다.
flush를 사용하시면, Tx를 제대로 담지 못했다는 에러가 발생 하실 겁니다.
딱히 에러는 없고, 단순히 Spring에서 해당 Transaction을 인식하고 처리하지 못하는 케이스가 발생 합니다.
한번 해보시고, 추가적으로 궁금하신 부분 질문주시면 감사하겠습니다!!
0
안녕하세요, 인프런 AI 인턴입니다. 리나님.
질문해 주신 내용에 대해 유사한 문제를 다룬 답변을 찾아 안내 드리겠습니다.
질문에 대한 간략한 설명:
1. 웹소켓과 @Transactional 사용 시 TransactionManager 설정 이유:
트랜잭션 경계 설정의 중요성: 웹소켓을 통한 메시지 전송 시, 동일한 세션을 여러 사용자와 공유하기 때문에 트랜잭션 경계를 명확히 두지 않으면 데이터 일관성 문제가 발생할 수 있습니다. @Transactional(transactionManager = "customTransactionManager")
를 사용하는 이유는 이러한 경계를 명확히 설정하여 데이터의 일관성을 보장하는 것입니다.
별도의 TransactionManager 필요성: 웹소켓과 일반 HTTP 요청은 트랜잭션 처리 방식이 다를 수 있습니다. 웹소켓의 특성상 세션 기반 동작이기 때문에, 이를 처리할 별도의 트랜잭션 전략이 필요할 수 있습니다. 다수의 연결에서 효율적인 트랜잭션 관리를 가능하게 하기 위해 커스텀 트랜잭션 매니저를 사용할 필요가 있습니다.
2. JPA의 @Transactional 사용 유무에 따른 문제:
JPA의 기본 트랜잭션 동작: JPA의 기본 save
메서드는 내부적으로 트랜잭션이 설정되어 있어 데이터베이스 작업을 안전하게 처리할 수 있습니다. 그러나 웹소켓 환경에서는 다소 불안정한 상황을 만들 수 있어 명시적으로 트랜잭션 경계를 설정해 주는 것이 좋습니다.
@Transactional의 제한적 응용: 기본적으로 리포지토리 메소드에서도 트랜잭션이 설정되어 있지만, 복잡한 웹 응용환경에서 명확한 트랜잭션 경계를 구현하기 위해 명시적인 트랜잭션 선언 및 커스텀 설정이 필요할 수 있습니다.
이와 같이 설정하면 데이터의 일관성을 높일 수 있고, 트랜잭션의 경계를 명확히 하여 문제가 발생할 여지를 줄일 수 있습니다. 웹소켓과 트랜잭션 관리에 대한 추가적인 고민은 위 유사한 질문 링크를 참조하셔서 더욱 깊이 있는 이해를 하실 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.