spring事物传播性

1.两种方式配置

注意:项目中如果两个都配置上了,本地测试后,发现xml的配置生效了,注解未生效

1.1 xml方式
<!--通知-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        -- 如果当前事务存在,就加入,没有就新建
        <tx:method name="save*" propagation="REQUIRED"/>
        <tx:method name="insert*" propagation="REQUIRED" />
        <tx:method name="add*" propagation="REQUIRES_NEW" />
        <tx:method name="create*" propagation="REQUIRED" />
        <tx:method name="delete*" propagation="REQUIRED" />
        <tx:method name="update*" propagation="REQUIRED" />
        <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
        <tx:method name="select*" propagation="SUPPORTS" read-only="true" />
        <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
    </tx:attributes>
</tx:advice>

切面
<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.pgf.memcached.service.*.*(..))"/>
</aop:config>
1.2 注解方式
@Transactional(propagation = Propagation.REQUIRES_NEW)//使用心得事物 还需要再spring配置文件中开启事务注解
//xml开启
<tx:annotation-driven transaction-manager="transactionManager"/>

2.事物常用的传播性

1、PROPOGATION_REQUIRES --需要在一个事务中执行
2、PROPOGATION_SUPPOTS --不需要在一个事务中执行,如果有事务,也可以执行
3 PROPOGATION_NOT_SUPPORTED --不支持在一个事务中执行,如果在一个正在运行的事务中执行,则会被挂起

5 PROPOGATION_NEVER --必须不在一个正在运行的事务中执行,则会抛出异常
6 PROPOGATION_MANDATORY --必须在一个正在运行的事务中执行,否则抛出异常
7 PROPOGATION_NEW --如果有一个事务正在执行,则挂起该事务,重开一个事务

4 PROPOGATION_NESTED --如果有一个事务a正在进行中,该事务被嵌套在a中

3.例子

@ResponseBody
    @RequestMapping(value = "/tx",method = RequestMethod.POST)
    public boolean testTx(@RequestBody TblKidsInfo tblKidsInfo){
        TblKidsInfo info = new TblKidsInfo();
        info.setAmount(BigDecimal.TEN);
        info.setAge(tblKidsInfo.getAge());
        info.setCreateDate(new Date());
        info.setName(tblKidsInfo.getName());
        info.setTeachId(tblKidsInfo.getTeachId());
        tblKidsInfoService.addKids(info); //两个service
        return true;
    }

 //默认使用数据库的隔离级别 传播性propagation_requierd
    @Transactional(propagation = Propagation.REQUIRED)
    public void addKids(TblKidsInfo tblKidsInfo) {
        tblKidsInfoMapper.insert(tblKidsInfo);

        System.out.println("kids add success");

        TblParentInfo info1 = new TblParentInfo();
        info1.setAmount(BigDecimal.TEN);
        info1.setAge(2222);
        info1.setCreateDate(new Date());
        info1.setName("2222");
        info1.setTeachId(2222);
        int a = 1/0;
        try {
            tblParentInfoService.addInfo(info1); //catch后,事物1正常执行
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

@Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public boolean addInfo(TblParentInfo info) {

        tblParentInfoMapper.insertSelective(info);
        System.out.println("parent add success");
        int i = 1/0;
        return true;
    }

Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7057564a]
JDBC Connection [com.mysql.jdbc.JDBC4Connection@7c7029a4] will be managed by Spring
==>  Preparing: insert into tbl_kids_info (ID, NAME, TEACH_ID, AGE, CREATE_DATE, AMOUNT ) values (?, ?, ?, ?, ?, ? ) 
==> Parameters: null, pgf太热(String), 12(Integer), 27(Integer), 2020-05-21 17:55:07.634(Timestamp), 10(BigDecimal)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7057564a]
kids add success
Transaction synchronization suspending SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7057564a] //**在此处挂起**
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@204a0948]
JDBC Connection [com.mysql.jdbc.JDBC4Connection@7705226d] will be managed by Spring
==>  Preparing: insert into tbl_parent_info ( NAME, TEACH_ID, AGE, CREATE_DATE, AMOUNT ) values ( ?, ?, ?, ?, ? ) 
==> Parameters: 2222(String), 2222(Integer), 2222(Integer), 2020-05-21 17:55:07.979(Timestamp), 10(BigDecimal)
<==    Updates: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@204a0948]
parent add success
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@204a0948]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@204a0948]
Transaction synchronization resuming SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7057564a]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7057564a]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7057564a]

从日志分析,执行第二个service时,第一个事物被挂起,创建第二个事物,关闭第二个事物,恢复第一个事物,在关闭第一个事物
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring框架中,事务的传播是指在一个方法中调用另一个方法时,事务应该如何进行传播。其中,REQUIRED是Spring事务传播最常用的一种类型。下面是对REQUIRED事务传播的详细解释: 1. 如果当前方法已经在一个事务中,则调用的方法将在同一个事务中运行。如果调用的方法发生异常并抛出了异常,则整个事务将回滚。 2. 如果当前方法没有在一个事务中,则调用的方法将开启一个新的事务并在其中运行。如果调用的方法发生异常并抛出了异常,则整个事务将回滚。 3. 如果当前方法没有在一个事务中,但调用的方法标有@Transactional注解并且使用REQUIRED传播,则调用的方法将加入当前方法所在的事务中。 4. 如果当前方法已经在一个事务中,但调用的方法标有@Transactional注解并且使用REQUIRED_NEW传播,则当前方法的事务将被挂起,调用的方法将在一个新的事务中运行。如果调用的方法发生异常并抛出了异常,则只有调用方法所在的事务会回滚,当前方法所在的事务不会回滚。 总之,使用REQUIRED传播可以确保方法在一个事务中运行,同时保证整个事务的一致和完整。但需要注意的是,如果方法的执行时间过长,可能会导致事务锁定时间过长,从而影响系统能。因此,在使用Spring事务时,应该根据具体情况选择合适的事务传播
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值