暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

开发中遇到的八种事务失效场景

682

1.数据库引擎不支持事务

  MySQL中,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB MySQL 5.5.5 开始的默认存储引擎是:InnoDB,之前默认的都是:MyISAM

2.没有被 Spring 管理

如例所示:

    // @Service


    public class OrderServiceImpl implements OrderService {


    @Transactional


    public void updateOrder(Order order) {


    update order


    }


    }
    复制

    如果把 @Service 注解注释掉,这个类就不会被加载成一个 Bean,那这个类就不会被 Spring 管理了,事务自然就失效了。

    3.方法不是 public

    以下来自 Spring 官方文档:

    When using proxies, you should apply the @Transactional annotation only to methods with public visibility. If you do annotate protected, private or package-visible methods with the @Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods.

    @Transactional 只能用于 public 的方法上,否则事务不会生效

    4.自身调用问题

      @Service


      public class OrderServiceImpl implements OrderService {


      public void update(Order order) {


      updateOrder(order);


      }


      @Transactional


      public void updateOrder(Order order) {


      // update order


      }


      }
      复制
        //示例2


        @Service


        public class OrderServiceImpl implements OrderService {


        @Transactional


        public void update(Order order) {


        updateOrder(order);


        }


        @Transactional(propagation = Propagation.REQUIRES_NEW)


        public void updateOrder(Order order) {


        // update order


        }


        }
        复制

          示例1 中,update方法上面没有加 @Transactional 注解,调用有 @Transactional 注解的 updateOrder 方法,updateOrder 方法上的事务无效

          示例2 中,update方法上面加 @Transactional 注解,调用有 @Transactional 注解的 updateOrder 方法,updateOrder 方法上的事务无效

        因为它们发生了自身调用,就调该类自己的方法,而没有经过 Spring 的代理类,默认只有在外部调用事务才会生效

        方法1:把methodA()methodB()分别放到不同的类里。

        方法2:自己注入自己,用注入的实例调用

          @Service


          public class TestService {


          @Autowired


          private TestService testService;




          @Transactional


          public void methodA(){


          }


          /**


          * 这里调用methodA() 的事务将会生效


          */


          public void methodB(){


          testService.methodA();


          }


          }
          复制

          5.数据源没有配置事务管理器

          如下代码所示,当前数据源若没有配置事务管理器,不生效

          @Bean

          public PlatformTransactionManager transactionManager(DataSource dataSource) {

          return new DataSourceTransactionManager(dataSource);

          }

          6.@Transactional的扩展配置不支持事务

          Propagation.NOT_SUPPORTED:表示不以事务运行,当前若存在事务则挂起。这表示不支持以事务的方式运行

            @Service


            public class OrderServiceImpl implements OrderService {


            @Transactional


            public void update(Order order) {


            updateOrder(order);


            }


            @Transactional(propagation = Propagation.NOT_SUPPORTED)


            public void updateOrder(Order order) {


            // update order


            }


            }
            复制

            7.异常被吃

            把异常吃了,不抛出来,事务不会回滚

              @Service


              public class OrderServiceImpl implements OrderService {


              @Transactional


              public void updateOrder(Order order) {


              try {


              // update order


              } catch {


              }


              }


              }
              复制

              8.异常类型错误

              再抛出一个异常

                @Service


                public class OrderServiceImpl implements OrderService {


                @Transactional


                public void updateOrder(Order order) {


                try {


                // update order


                } catch {


                throw new Exception("更新错误");


                }


                }


                }
                复制

                这样事务不生效,因为默认回滚的是:RuntimeException,如果想触发其他异常的回滚,需要在注解上配置一下,如:@Transactional(rollbackFor = Exception.class)


                文章转载自琢磨先生DataBase,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论