복붙노트

[SPRING] Spring 트랜잭션 경계 이해하기

SPRING

Spring 트랜잭션 경계 이해하기

나는 의심을 분명히하려고 노력 중이다. Spring 트랜잭션 경계는 다음 예제와 같습니다.

@Transactional(propagation=Propagation.REQUIRES_NEW)
public void test() {    
    test1();
    test2();        
}

@Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly=false)
public void test1() {
    this.jdbcTemplate.execute("INSERT INTO TEST VALUES('T', 'C2', 0, 1)");      
}

@Transactional(propagation=Propagation.SUPPORTS, isolation=Isolation.READ_UNCOMMITTED, readOnly=true)
public void test2() {
    System.out.println(this.jdbcTemplate.queryForInt("select count(*) from TEST"));         
}

test2 ()가 test1 ()에 의해 커밋 된 데이터를 읽지 않아야 할 때마다 test2 () 메서드를 test1 ()에서 분리하려고합니다. 전파 또는 격리 특성을 사용하여이 시나리오를 처리하는 것이 가능하다는 조언을 구하십시오.

미리 감사드립니다.

해결법

  1. ==============================

    1.트랜잭션 속성은 외부 호출에 적용되며 내부 메소드는 사용자의 케이스와 같은 Bean 메소드에 의한 호출이 아닙니다. 호출에 트랜잭션 경계를 적용하려면 아래와 같이 빈 인스턴스를 주입해야합니다. 하지만 좋은 습관은 아니라고 나는 생각하지 않는다. 올바른 방법은 다른 스프링 빈을 정의하고 이전 빈과 연관시켜 테스트 메소드를이 새 빈에 두는 것이다.

    트랜잭션 속성은 외부 호출에 적용되며 내부 메소드는 사용자의 케이스와 같은 Bean 메소드에 의한 호출이 아닙니다. 호출에 트랜잭션 경계를 적용하려면 아래와 같이 빈 인스턴스를 주입해야합니다. 하지만 좋은 습관은 아니라고 나는 생각하지 않는다. 올바른 방법은 다른 스프링 빈을 정의하고 이전 빈과 연관시켜 테스트 메소드를이 새 빈에 두는 것이다.

    @Service("yourBean")
    @Transactional
    public class YourBeanClass implement IYourBean {
    
       @Resource(name="yourBean")
        IYourBean yourBean;
    
            @Transactional(propagation=Propagation.REQUIRED)
        public void test() {    
            yourBean.test1();
            yourBean.test2();       
        }
    
        @Transactional(propagation=Propagation.REQUIRED)
        public void test1() {
            this.jdbcTemplate.execute("INSERT INTO TEST VALUES('T', 'C2', 0, 1)");      
        }
    
        @Transactional(propagation=Propagation.NOT_SUPPORTED)
        public void test2() {
            System.out.println(this.jdbcTemplate.queryForInt("select count(*) from TEST"));         
        }
    

    }

    이 특별한 문제를 해결하기위한 대안과 더 좋은 방법;

     @Service("otherBean")
        @Transactional
        public class OtherBeanClass implement IOtherBean {
    
         @Autowired
         IYourBean yourBean;
    
          @Transactional(propagation=Propagation.REQUIRED)
            public void test() {    
                yourBean.test1();
                yourBean.test2();       
            }
    
       }
    
    
    
        @Service("yourBean")
        @Transactional
        public class YourBeanClass implement IYourBean {
    
    
    
            @Transactional(propagation=Propagation.REQUIRED)
            public void test1() {
                this.jdbcTemplate.execute("INSERT INTO TEST VALUES('T', 'C2', 0, 1)");      
            }
    
            @Transactional(propagation=Propagation.NOT_SUPPORTED)
            public void test2() {
                System.out.println(this.jdbcTemplate.queryForInt("select count(*) from TEST"));         
            }
    }
    
  2. ==============================

    2.test ()는 SUPPORTS 여야합니다. 따라서 기존 TX가 있으면 test1 ()에 전달됩니다. 삽입이 실제로 커밋되도록 test1 ()이 필수적이어야합니다. test2 ()는 REQUIRES_NEW 여야합니다.

    test ()는 SUPPORTS 여야합니다. 따라서 기존 TX가 있으면 test1 ()에 전달됩니다. 삽입이 실제로 커밋되도록 test1 ()이 필수적이어야합니다. test2 ()는 REQUIRES_NEW 여야합니다.

  3. from https://stackoverflow.com/questions/5538262/understanding-spring-transaction-boundaries by cc-by-sa and MIT license