关于spring事物的一些测试

3 篇文章 0 订阅

spring事物的传播方式主要有以下几种:

PROPAGATION_REQUIRED:支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY:支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务,如果当前没有事务,就新建一个事务。

下面我建一个web工程开始测试以上几种事物。

TestService:主要是往aa表中插入一条数据,然后调用TestService2的outterYesSave方法。

package com.syz.tx.service;

import org.springframework.jdbc.core.JdbcTemplate;

public class TestService {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    private TestService2 testService2;

    public void setTestService2(TestService2 testService2) {
        this.testService2 = testService2;
    }

    public void currYesSave() {
        String sql = "insert into aa(name,gold) values(?,?)";
        jdbcTemplate.update(sql, new Object[] { "cur_yes", 100.0 });
        testService2.outterYesSave();
    }

}
TestService2:往bb表中插入一条数据。

package com.syz.tx.service;

import org.springframework.jdbc.core.JdbcTemplate;

public class TestService2 {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void outterYesSave() {
        String sql = "insert into bb(name,money) values(?,?)";
        jdbcTemplate.update(sql, new Object[] { "out_yes", 200.0 });
    }
}
开始测试:

1.TestService.currYesSave:propagation="REQUIRED",TestService2.outterYesSave:propagation="REQUIRED"

调用TestService.currYesSave执行结果:

可以看到执行TestService.currYesSave时创建了一个事物,而TestService2.outterYesSave时,它直接引用了上面已经存在的事物。解释了:PROPAGATION_REQUIRED:支持当前事务。

2.TestService.currYesSave:propagation="SUPPORTS",TestService2.outterYesSave:propagation="REQUIRED"

调用TestService.currYesSave执行结果:


可以看到执行TestService.currYesSave时,直接创建了一个连接就执行了sql,此处没有开启事物。解释了:PROPAGATION_SUPPORTS:如果当前没有事务,就以非事务方式执行。执行TestService2.outterYesSave时创建了一个事物。解释了:PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务。

3.TestService.currYesSave:propagation="REQUIRED",TestService2.outterYesSave:propagation="SUPPORTS"

调用TestService.currYesSave执行结果:


可以看到执行TestService.currYesSave时,创建了一个事物。执行TestService2.outterYesSave时直接引用了上面已经存在的事物。解释了:PROPAGATION_SUPPORTS:支持当前事务。

4.TestService.currYesSave:propagation="REQUIRED",TestService2.outterYesSave:propagation="MANDATORY"

调用TestService.currYesSave执行结果:

可以看到执行TestService.currYesSave时,创建了一个事物。执行TestService2.outterYesSave时直接引用了上面已经存在的事物。解释了:PROPAGATION_MANDATORY:支持当前事务。

5.TestService.currYesSave:propagation="SUPPORTS",TestService2.outterYesSave:propagation="MANDATORY"

调用TestService.currYesSave执行结果:

可以看到执行TestService.currYesSave时,直接就执行了sql。执行TestService2.outterYesSave时,发现没有事物,直接就报异常了。解释了:PROPAGATION_MANDATORY:如果当前没有事务,就抛出异常。在这里说一下此次数据库的数据,aa表新加了一条数据,bb表没有。

6.TestService.currYesSave:propagation="SUPPORTS",TestService2.outterYesSave:propagation="REQUIRES_NEW"

调用TestService.currYesSave执行结果:


可以看到执行TestService.currYesSave时,直接就执行了sql。执行TestService2.outterYesSave时,新建了一个事物。解释了:PROPAGATION_REQUIRES_NEW:新建事务。

7.TestService.currYesSave:propagation="REQUIRED",TestService2.outterYesSave:propagation="REQUIRES_NEW"

调用TestService.currYesSave执行结果:

可以看到执行TestService.currYesSave时,创建了一个事物。执行TestService2.outterYesSave时,挂起当前事物,新建了一个事物。解释了:PROPAGATION_REQUIRES_NEW:如果当前存在事务,把当前事务挂起。

8.TestService.currYesSave:propagation="REQUIRED",TestService2.outterYesSave:propagation="NOT_SUPPORTED"

调用TestService.currYesSave执行结果:


可以看到执行TestService.currYesSave时,创建了一个事物。执行TestService2.outterYesSave时,挂起当前事物,然后直接执行了sql。解释了:PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

9.TestService.currYesSave:propagation="REQUIRED",TestService2.outterYesSave:propagation="NEVER"

调用TestService.currYesSave执行结果:


可以看到执行TestService.currYesSave时,创建了一个事物。执行TestService2.outterYesSave时,直接就抛出异常了。解释了:PROPAGATION_NEVER:如果当前存在事务,则抛出异常。此时数据库中aa和bb都没有加进数据。aa插入语句回滚了,bb插入语句没执行。

10.TestService.currYesSave:propagation="SUPPORTS",TestService2.outterYesSave:propagation="NEVER"

调用TestService.currYesSave执行结果:


可以看到执行TestService.currYesSave时,直接执行了sql。执行TestService2.outterYesSave时,直接直接执行了sql。解释了:PROPAGATION_NEVER:以非事务方式执行。

11.TestService.currYesSave:propagation="SUPPORTS",TestService2.outterYesSave:propagation="NESTED"

调用TestService.currYesSave执行结果:

可以看到执行TestService.currYesSave时,直接执行了sql。执行TestService2.outterYesSave时,新建了一个事物。解释了:PROPAGATION_NESTED:如果当前没有事务,就新建一个事务。

12.TestService.currYesSave:propagation="REQUIRED",TestService2.outterYesSave:propagation="NESTED"

调用TestService.currYesSave执行结果:

可以看到执行TestService.currYesSave时,创建了一个事物。执行TestService2.outterYesSave时,创建了一个嵌套事物。解释了:PROPAGATION_NESTED:支持当前事务,如果当前事务存在,则执行一个嵌套事务。那么此时创建了几个事物呢?答案是一个,注意和PROPAGATION_REQUIRES_NEW的区别,这里是Create nested transaction,而REQUIRES_NEW是Create new transaction,故7中有两个事物。

测试完了,说一下感受吧。虽然事物的传播方式有7种,但我们经常用的估计就两种,REQUIRED和SUPPORTS,对于有更新操作的设置为REQUIRED,其它都设置为SUPPORTS,一般就能满足我们的需求了。

以上是ServiceA.methodA中调用ServiceB.methodB的情况,下面我们来看看ServiceA.methodA中调用ServiceA.methodB的情况:

TestService3:methodA向aa表插入数据,然后调用methodB。mehtodB向bb表插入数据。

package com.syz.tx.service;

import org.springframework.jdbc.core.JdbcTemplate;

public class TestService3 {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void methodA() {
        String sql = "insert into aa(name,gold) values(?,?)";
        jdbcTemplate.update(sql, new Object[] { "cur_yes", 100.0 });
        methodB();
    }

    public void methodB() {
        String sql = "insert into bb(name,money) values(?,?)";
        jdbcTemplate.update(sql, new Object[] { "out_yes", 200.0 });
    }

}

1.TestService3.mehtodA:propagation="SUPPORTS",TestService3.methodB:propagation="REQUIRES_NEW"

调用TestService3.methodA结果:

可以看到执行TestService3.methodA时,直接执行了sql,执行TestService3.methodB时,也是直接执行了sql。测试结果:完全没有创建事物。

2.TestService3.mehtodA:propagation="SUPPORTS",TestService3.methodB:propagation="REQUIRES_NEW"

调用TestService3.methodA结果:

可以看到执行TestService3.methodA时,创建了一个事物。执行TestService3.methodB时,直接执行了sql。测试结果:只创建了一个事物。

总结:通过以上两个测试,可以得出结论,在同一个类中,嵌套调用本类的其它方法,相当于直接把嵌套方法复制到了当前方法。对于是否创建了事物,得看当前方法有没有事物。如1,methodA无事物,调用methodB,结果没有创建事物;又如2,methodA有事物,调用methodB,结果methodB被合并到methodA了,共用一个事物。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值