事务注解失效的六种场景

本文介绍Spring事务注解失效的六种场景,包括方法修饰为protected和private、rollback设置错误、异常信息被捕获、同类之间方法调用、传播行为配置错误以及存储引擎本身不支持事务,还提及了环境搭建相关的sql、pom和配置文件,并给出代码地址。

事务注解失效的六种场景

环境搭建

sql

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) DEFAULT NULL COMMENT '姓名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=162 DEFAULT CHARSET=utf8;

pom

 <dependencies>
       <!-- spring框架运行的必须jar包 -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context</artifactId>
           <version>5.0.2.RELEASE</version>
       </dependency>
       <!-- spring框架对于jdbc进行的简单封装 -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-jdbc</artifactId>
           <version>5.0.2.RELEASE</version>
       </dependency>
       <!-- spring框架对于事务支持的jar包 -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-tx</artifactId>
           <version>5.0.2.RELEASE</version>
       </dependency>
       <!-- spring框架的测试包 -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-test</artifactId>
           <version>5.0.2.RELEASE</version>
       </dependency>
       <!-- spring框架提供对AspectJ框架的整合 -->
       <dependency>
           <groupId>org.aspectj</groupId>
           <artifactId>aspectjweaver</artifactId>
           <version>1.8.7</version>
       </dependency>
       <!-- mysql数据库 -->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.6</version>
       </dependency>
       <!-- 测试 -->
       <dependency>
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
           <version>4.12</version>
       </dependency>
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
           <version>1.16.4</version>
       </dependency>
   </dependencies>

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 配置spring提供的数据库连接池 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:3306/spring"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>

    <!-- jdbcTemplate的配置 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <context:component-scan
            base-package="com"></context:component-scan>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 启用事务注解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
</beans>

1 方法修饰是protected和provite

/**
     * protected  事务会失效
     * private    不允许添加事务注解
     */
    @Transactional
    protected   void  addProtected(Student student){
        jdbcTemplate.update("insert into student (name) values (?);",
                student.getName());
        int i=1/0;
    }

2 rollback设置错误

/**
     * 设置异常 事务失效
     * @param student
     * @throws FileNotFoundException
     */
    @Transactional(rollbackFor = Exception.class)
    public  void  addRollBackFor(Student student) throws FileNotFoundException {
        // @Transactional
        studentService.add(student);
        //事务失效
        throw  new  FileNotFoundException("");
    }

3 异常信息被捕获

/**
     * 异常捕获 事务失效
     * @param student
     */
    @Transactional
    public void addTryCatch(Student student) {

        try {
            studentService.add(student);
            int i=1/0;
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }

4 同类之间方法调用

 /**
     * 
     * 这种场景复现有一个坑 可以使用REQUIRED和REQUIRES_NEW 配合使用
     * @param student
     */
    @Transactional
    public void addBySameClass(Student student) {
      /*  addError(student);等价于 jdbcTemplate.update("insert into student (name) values (?);",
                student.getName());*/
        //注释的代码无法复现 需要使用下面的方法
        studentService.addError(student);
        throw  new RuntimeException("");
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void addError(Student student) {
        jdbcTemplate.update("insert into student (name) values (?);",
                student.getName());

    }

5 传播行为配置错误

5.1 传播行为是SUPPORTS
 /**
     * 自身不支持事务
     * @param student
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public  void addBySupports(Student student){
        jdbcTemplate.update("insert into student (name) values (?);",
                student.getName());
        int i=1/0;
    }
5.2 传播行为是NOT_SUPPORTED
 @Transactional
    public  void  addByNotSupportsTest(Student student){
    // addByNotSupports(student); // 这样是有事务的
       studentService.addByNotSupports(student);
    }

    /**
     * NOT_SUPPORTED 已非事务状态运行
     * @param student
     */
    @Transactional(propagation = Propagation.NOT_SUPPORTED)
    public  void addByNotSupports(Student student){
        jdbcTemplate.update("insert into student (name) values (?);",
                student.getName());
        int i=1/0;
    }
5.3 传播行为是NEVER
 /**
     * NEVER 已非事务状态运行  存在事物就抛出异常信息
     * @param student
     */
    @Transactional(propagation = Propagation.NEVER)
    public  void addByNever(Student student){
        jdbcTemplate.update("insert into student (name) values (?);",
                student.getName());
    }

    @Transactional
    public  void  addByNeverTest(Student student){
        //addByNever(student); 这种场景是无法验证的
        studentService.addByNever(student);
    }

6 存储引擎本身不支持事务

Myisam该存储引擎自身不支持事务

代码地址

https://gitee.com/baizeze/transactional.git
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值