1、数据库引擎不支持事务
这里以 MySQL 为例,其 MyISAM 引擎是不支持事务操作的,InnoDB 才是支持事务的引擎,一般要支持事务都会使用 InnoDB。
根据 MySQL 的官方文档:
https://dev.mysql.com/doc/refman/5.5/en/storage-engine-setting.html
从 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 的方法上,否则事务不会失效,如果要用在非 public 方法上,可以开启 AspectJ 代理模式。
 
4、自身调用问题
 
来看两个示例:
@Service
public class OrderServiceImpl implements OrderService {
 
    public void update(Order order) {
        updateOrder(order);
    }
 
    @Transactional
    public void updateOrder(Order order) {
        // update order
    }
}
update方法上面没有加 @Transactional 注解,调用有 @Transactional 注解的 updateOrder 方法,updateOrder 方法上的事务管用吗?
再来看下面这个例子:
@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
    }
 
}
这次在 update 方法上加了 @Transactional,updateOrder 加了 REQUIRES_NEW 新开启一个事务,那么新开的事务管用么?
这两个例子的答案是:不管用!
因为它们发生了自身调用,就调该类自己的方法,而没有经过 Spring 的代理类,默认只有在外部调用事务才会生效,这也是老生常谈的经典问题了。
这个的解决方案之一就是在的类中注入自己,用注入的对象再调用另外一个方法,这个不太优雅,另外一个可行的方案可以参考《Spring 如何在一个事务中开启另一个事务?》这篇文章。
 
5、数据源没有配置事务管理器
 
 
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
    return new DataSourceTransactionManager(dataSource);
}
如上面所示,当前数据源若没有配置事务管理器,那也是白搭!
 
6、不支持事务
 
来看下面这个例子:
@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
    }
 
}
Propagation.NOT_SUPPORTED: 表示不以事务运行,当前若存在事务则挂起,详细的可以参考《事务隔离级别和传播机制》这篇文章。
都主动不支持以事务方式运行了,那事务生效也是白搭!
 
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)
这个配置仅限于 Throwable 异常类及其子类。
总结
本文总结了八种事务失效的场景,其实发生最多就是自身调用、异常被吃、异常抛出类型不对这三个了。

spring事务不生效8种原因的更多相关文章

  1. Spring事务失效的2种情况

    使用默认的事务处理方式 因为在java的设计中,它认为不继承RuntimeException的异常是”checkException”或普通异常,如IOException,这些异常在java语法中是要求 ...

  2. Spring事务管理的四种方式(以银行转账为例)

    Spring事务管理的四种方式(以银行转账为例) 一.事务的作用 将若干的数据库操作作为一个整体控制,一起成功或一起失败.   原子性:指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不 ...

  3. Spring事务不生效问题

    事务未生效可能造成严重的数据不一致性问题,因而保证事务生效至关重要.Spring事务是通过Spring aop实现的,所以不生效的本质问题是spring aop没生效,或者说没有代理成功,所以有必要了 ...

  4. 事务管理(下) 配置spring事务管理的几种方式(声明式事务)

    配置spring事务管理的几种方式(声明式事务) 概要: Spring对编程式事务的支持与EJB有很大的区别.不像EJB和Java事务API(Java Transaction API, JTA)耦合在 ...

  5. Spring事务配置的五种方式(转发)

    Spring事务配置的五种方式(原博客地址是http://www.blogjava.net/robbie/archive/2009/04/05/264003.html)挺好的,收藏转发 前段时间对Sp ...

  6. Spring事务配置的五种方式和spring里面事务的传播属性和事务隔离级别

    转: http://blog.csdn.net/it_man/article/details/5074371 Spring事务配置的五种方式 前段时间对Spring的事务配置做了比较深入的研究,在此之 ...

  7. Spring基础系列-Spring事务不生效的问题与循环依赖问题

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9476550.html 一.提出问题 不知道你是否遇到过这样的情况,在ssm框架中开发we ...

  8. 聊聊spring事务失效的12种场景,太坑了

    前言 对于从事java开发工作的同学来说,spring的事务肯定再熟悉不过了. 在某些业务场景下,如果一个请求中,需要同时写入多张表的数据.为了保证操作的原子性(要么同时成功,要么同时失败),避免数据 ...

  9. spring事务失效的12种场景

    一 事务不生效 1.访问权限问题 java的访问权限主要有四种:private<default<protected<public. 把有某些事务方法,定义了错误的访问权限,就会导致事 ...

  10. Spring事务管理的三种方式

    一 .第一种:全注解声明式事务 Xml代码 复制代码 收藏代码 .<?xml version="1.0" encoding="UTF-8"?> .& ...

随机推荐

  1. C++实现有序表--顺序表的合并操作代码

    #include<iostream>#include<cstdlib>//C++动态分配存储空间using namespace std;#define OK 1#define ...

  2. Python3之并发(四)---线程锁

    一.线程锁 保证多线程数据的一致性,对锁内的资源进行锁定,同一时间只能有一个线程来修改共享的数据多个线程同时加了同一个锁对象时,先获取到锁的线程会继续运行,未获取到锁的线程会处于堵塞状态,直到前面的线 ...

  3. 【SQL Server】存储过程带参数输出——output

    在SQL Server 中,如果要用一个存储过程返回字符串应该怎么做?用output参数. 错误方式 接下来,展示一下,常见的错误方法 CREATE PROCEDURE testString AS B ...

  4. google api 后端打点上报

    https://developers.google.com/analytics/devguides/collection/protocol/ga4/sending-events?client_type ...

  5. C# 下载文件 断点续传

    /// <summary> /// 普通文件下载 /// </summary> /// <param name="URL"></param ...

  6. 实时平台-Flink篇

    Flink任务统一通过实时平台统一管理的好处不用多说,这里简单介绍下实时平台-Flink模块的功能以及实现. 主要分为两大块 一.任务管理 任务管理主要包括任务的提交.暂停.下线.重启.历史版本回滚. ...

  7. 在Unity3D中开发的角色视觉系统插件Sight Detect System

    Sight-Detect-System 这款Sight Detect System插件由本人用Unity3D所开发,它在游戏中可以成为角色的视觉感知系统. 如果你想开发潜行类游戏时,那么这款视觉插件非 ...

  8. js 基础篇--保留字

    1.js把一些标识符拿出来用作自己的关键字.因此,就不能再在程序中把这些关键字用作标识符了: 1 break delete function return typeof 2 case do if sw ...

  9. Spring之IOC(控制反转)入门理解

    在面向对象编程中,我们经常处理处理的问题就是解耦,程序的耦合性越低表明这个程序的可读性以及可维护性越高(假如程序耦合性过高,改一处代码通常要对其他地方也要做大量修改,难以维护).控制反转(Invers ...

  10. jmeter 压测的执行步骤步骤

    一.设置测试参数 如图 Number of Threads:总共起多少个线程. Ramp-UP Period(in seconds):多少秒启动完所有线程. loop Count:循环次数 Sched ...