기록창고

@Transactional 본문

MSA

@Transactional

방금시작한사람 2021. 9. 19. 06:22

트랜잭션을 열때 하지 말아야할 것.. 😢

 

트랜잭션 사이에 기이이인 무언가을 넣지 말아야함

 

기이이인 무언가란?

 

시간이 오래 걸리는 연산 - 이런건 연산을 마치고 결과만 저장할때 

외부요청 - 레디스든 msa 구조라서 다른 곳을 다녀와야 한다는 등등..

외부의 장애가 바로 전파된다..

 

트랜잭션을 열고, 커넥션을 잡고 A 라는 곳에 요청을 보냇는데 죽거나 장애가 있어서타임아웃을기다리게 된다면.. 

어흑.. 바로 커넥션 풀에 있는거 다 쓰고 모든 요청이 디비만 기다리다가 다 500 ...

 

그래서 상태처리가 중요한 요청은 request 로 기록을 해두고, 요청을 보낸 다음에 다시 상태를 done 이나 fail 처리한다.

 

class AService {
    fun sendMoney(to: String, from: String, amount: Long) {
    	val log = moneyRepository.saveRequest(to, from, amount, REQEEST)
        
        val result = moneyService.sendMoney(to, from, amount)
        
        if(result == SUCCESS) {
        	moneyRepository.save(log.successSendMoney())
        } else {
        	moneyRepository.save(log.failSendMoney())
        }
    }
}

트랜잭션 어노테이션이 있다고 바로 트랜잭션이 시작되는게 아니고
함수 첫줄부터 적용되는게 아니라, 디비에 무언가를 할때부터 시작된다.

 

class Service(
    private val repo: Repo,
    private val redis: RedisService
) {
  
    @Transactional
    fun saveSomething(key: String) {
        // 트랜잭션은 실제 디비에 무언가를 하기 전까지 열리지 않는다
        // 따라서 redis.get 는 영향은 주지 않음
    	val value = redis.get(key)
        
        repo.save(value)
    }

    @Transactional
    fun getAndSaveRedis(key: String) {
        val value = repo.findByKey(key)
        
        // 이친구는 트랜잭션이 닫히지않기 때문에, 영향을 줌
        // 이런건 함수 밖에서 하거나, findByKey에 트랜잭션을 걸고, 이 함수에 트랜잭션 어노테이션을 빼자
        redis.set(key, value)
    }
}

'MSA' 카테고리의 다른 글

DB Connection 이 부족한 경우  (0) 2021.09.12
circuit이 없을때 과 timeout 이 긴 경우  (0) 2021.06.05
Comments