Java笔记-spring-mvc+mybatis注解方式事务管理

Step1:更改spring的配置文件(applicationContext.xml)

<!-- 事务管理器 -->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>

Step2:修改方法,增加事务配置(controller或者service中都可以)

@Transactional一般加在类上或者类中的public方法上,当作用在类上时候,该类所有的public方法都具有该类型的事务属性。如果作用在具体的方法上面,方法上的注解会覆盖类上的注解

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public int addPlan(Plan plan) {
        plan.setCreateAt(new Date());
        plan.setUpdateAt(new Date());
        return planMapper.add(plan);
    }

Step3:测试

@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public int addPlan(Plan plan) {
        plan.setCreateAt(new Date());
        plan.setUpdateAt(new Date());
        int test = 1/0; // 手动触发异常
        return planMapper.add(plan);
    }

@Transactional参数说明

参数说明
readOnly 是否是只读事务,true表示只读,false表示读写
timeout 事务超时秒数,默认值-1表示永不超时
isolation 隔离级别,例如(isolation = Isolation.READ_UNCOMMITTED)
propagation 事务传播行为,见表propagation说明,例如@Transactional(propagation=Propagation.REQUIRED)
rollbackFor 需要回滚的异常类数组,例如</br>单一异常类:@Transactional(rollbackFor=RuntimeException.class)</br> 多个异常类:@Transactional(rollbackFor={IndexOutOfBoundsException.class, OutOfMemoryException.class})
noRollbackFor 不需要进行回滚的异常类数组,......
rollbackForClassName 需要进行回滚的异常类名称数组,例如</br>单一异常类名称:@Transactional(rollbackForClassName="RuntimeException") </br>多个异常类名称:@Transactional(rollbackForClassName={"IndexOutOfBoundsException","OutOfMemoryException.class"})
noRollbackForClassName 不需要进行回滚的异常类名称数组,......

propagation说明

参数说明
REQUIRED 有事务,加入事务,没有新建一个
NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起
MANDATORY 使用当前的事务,如果当前没有事务,就抛出异常
NEVER 以非事务方式执行,如果当前存在事务,则抛出异常
SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行
NESTED 如果当前存在事务,则在嵌套事务内执行,如果当前没有事务,则执行与REQUIRED类似的操作

注意事项

  • @Transactional注解起作用的方法必须是public类型
  • 方法必须抛出异常
  • MySQL数据库类型的选择(InnoDB)

Q:按照流程配置,但是不回滚,为什么?

这里分享一下本人遇到的一个神坑,有可能对读者有些帮助

A:如果试了各种方法都不行,再重新看下数据库的引擎类型

因为你可能并没有成功换掉db的引擎

我们知道,MyISAM并不支持事务,所以我们想要事务生效,必须修改该表的引擎为InnoDB。于是,我们在网上搜了一下如何修改引擎,于是我们执行了如下操作:alter table table_name engine=innodb;操作完之后,显示操作成功了,这样我想当然的认为该表已经成功变成了InnoDB引擎。但是,坑来了,其实可能并没有替换好。执行替换操作语句之后,请一定执行操作:show table status from mydb;查看一下表的信息,确认一下。那么,这个原因是啥呢,我又执行了语句:show engines;发现一个细节,InnoDB对应的状态是DISABLED。原来,我的InnoDB被禁用了,所以导致了上面的问题。(巨坑的MySQL,这话情况下执行语句,竟然不报错提醒)正确的操作方法如下:

  • 查看数据库支持的引擎列表(如果不支持,请自行百度解决)
show engines;
  • 修改引擎
alter table table_name engine=innodb;
  • 查看修改结果
show table status from mydb;


阅读原文

 

posted on 2021-02-04 18:05  生活费  阅读(121)  评论(0编辑  收藏  举报

导航