fix: 코루틴 내 트랜잭션 간 조회 안 되는 문제 해결

- 각 트랜잭션을 TransactionTemplate 블록으로 분리하여 커밋 시점 명확화
- 두 번째 트랜잭션에서 entityManager.clear() 호출로 1차 캐시 무시
- CoroutineExceptionHandler 추가로 비동기 예외 로깅 처리
- @PreDestroy 추가로 서비스 종료 시 CoroutineScope 정리
This commit is contained in:
Klaus 2025-05-22 12:25:17 +09:00
parent b92810efd2
commit af352256e9
1 changed files with 17 additions and 2 deletions

View File

@ -1,7 +1,9 @@
package kr.co.vividnext.sodalive.useraction package kr.co.vividnext.sodalive.useraction
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kr.co.vividnext.sodalive.content.order.OrderRepository import kr.co.vividnext.sodalive.content.order.OrderRepository
import kr.co.vividnext.sodalive.fcm.FcmService import kr.co.vividnext.sodalive.fcm.FcmService
@ -14,6 +16,8 @@ import org.slf4j.LoggerFactory
import org.springframework.stereotype.Service import org.springframework.stereotype.Service
import org.springframework.transaction.support.TransactionTemplate import org.springframework.transaction.support.TransactionTemplate
import java.time.LocalDateTime import java.time.LocalDateTime
import javax.annotation.PreDestroy
import javax.persistence.EntityManager
@Service @Service
class UserActionService( class UserActionService(
@ -24,10 +28,15 @@ class UserActionService(
private val memberPointRepository: MemberPointRepository, private val memberPointRepository: MemberPointRepository,
private val transactionTemplate: TransactionTemplate, private val transactionTemplate: TransactionTemplate,
private val fcmService: FcmService private val fcmService: FcmService,
private val entityManager: EntityManager
) { ) {
private val coroutineScope = CoroutineScope(Dispatchers.IO) private val coroutineScope = CoroutineScope(
Dispatchers.IO + CoroutineExceptionHandler { _, e ->
logger.error("포인트 지급 또는 알림 실패: ${e.message}")
}
)
fun recordAction( fun recordAction(
memberId: Long, memberId: Long,
@ -53,6 +62,7 @@ class UserActionService(
if (isAuth) { if (isAuth) {
try { try {
transactionTemplate.execute { transactionTemplate.execute {
entityManager.clear()
val policy = policyRepository.findByActionTypeAndIsActiveTrue(actionType, now) val policy = policyRepository.findByActionTypeAndIsActiveTrue(actionType, now)
if (policy != null) { if (policy != null) {
val policyType = policy.policyType val policyType = policy.policyType
@ -146,6 +156,11 @@ class UserActionService(
} }
} }
@PreDestroy
fun onDestroy() {
coroutineScope.cancel("UserActionService 종료")
}
companion object { companion object {
private val logger = LoggerFactory.getLogger(UserActionService::class.java) private val logger = LoggerFactory.getLogger(UserActionService::class.java)
} }