Java 理解Spring事务边界
我试图用下面的例子来澄清我对w.r.t.Spring交易边界的疑虑Java 理解Spring事务边界,java,spring,Java,Spring,我试图用下面的例子来澄清我对w.r.t.Spring交易边界的疑虑 @Transactional(propagation=Propagation.REQUIRES_NEW) public void test() { test1(); test2(); } @Transactional(propagation=Propagation.NOT_SUPPORTED, readOnly=false) public void test1() { this.
@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()分离,即每次调用test()时,test2()都不应读取test1()提交的数据。
请告知是否可以使用传播或隔离属性处理此场景
提前感谢。test()可能应该是受支持的,因此如果存在一个现有的TX,它将被传播到test1()。test1()应该是必需的,这样您的insert就可以实际提交了。
test2()应该是新的。事务属性应用于外部调用,而不是像您的案例那样由bean方法进行的内部调用。如果您想将事务边界应用于您的调用,您应该注入您的bean实例,如下所示。但是我认为这不是一个好的做法,我不推荐。。正确的方法是定义另一个Springbean并将其与您以前的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"));
}
}
哦,对了,我无法理解是什么让代码在一开始看起来很奇怪。事实上,test()中的test1和test2调用可能会忽略事务性。另外,我不确定不支持是test2的安全选择。在某些情况下,它不会导致提交现有事务吗?我建议REQUIRES_NEW,它看起来更安全,因为它只会抓取另一个数据库连接。不,它不会导致当前事务提交,当前事务在执行不受_支持的bean方法期间被挂起,当它完成其执行时,原始事务被恢复。。