开发者

Understanding Spring Transaction boundaries

开发者 https://www.devze.com 2023-02-22 10:36 出处:网络
I am trying to clear my doubts w.r.t. Spring Transaction boundaries with following example. @Transactional(propagation=Propagation.REQUIRES_NEW)

I am trying to clear my doubts w.r.t. Spring Transaction boundaries with following example.

@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=Propa开发者_如何学Cgation.SUPPORTS, isolation=Isolation.READ_UNCOMMITTED, readOnly=true)
public void test2() {
    System.out.println(this.jdbcTemplate.queryForInt("select count(*) from TEST"));         
}

I want to isolate test2() method from test1() that is each time test() is called test2() should not read the data committed by test1(). Please advice is it possible to handle this scenario using propagation or isolation attributes.

Thanks in advance.


Transaction attributes are applied to external calls , not internal calls made by bean method such as your case. If you want transaction boundaries applied to your call, you should inject your bean instance such as below. But I think that it is not good practice, I would not recommend.. The right way to accomplish is to define another spring bean and associate it with your previous bean and put your test method to this new 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"));         
    }

}

Alternative and better way to solve this particular problem ;

 @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"));         
        }
}


test() should probably be SUPPORTS, so if there is an existing TX, it will be propagated to test1(). test1() should be REQUIRED so your insert actually commits. test2() should be REQUIRES_NEW.

0

精彩评论

暂无评论...
验证码 换一张
取 消