要点1 Spring事务管理方法编程式事务(TransactionTemplate、PlatformTransactionManager)

声明式事务(配置式、注解式)

2 Spring 注解 @Transactional2.1 @Transactional 配置属性含义

事务传播行为

事务隔离级别

事务回滚机制

2.2 @Transactional 添加规则

1 Spring 事务管理方法

Spring 事务管理分为:编码式和声明式的两种方式:

1 编程式事务:

允许用户在代码中精确定义事务的边界。

实现方式:使用 TransactionTemplate (推荐使用)

直接使用底层的 PlatformTransactionManager

2 声明式事务

基于AOP,有助于用户将操作与事务规则进行解耦。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

实现方式:配置文件(xml)中做相关的事务规则声明

基于@Transactional 注解的方式(推荐使用,显然基于注解的方式更简单易用。)

声明式事务管理明显优于编程式事务管理,这正是Spring倡导的非侵入式开发方式。声明式事务管理使业务代码不受污染,一个普通的POJO对象,只要加上注解就可以获得完全的事务支持;和编程式事务相比,声明式事务唯一不足地方是,后者的最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。但是即便有这样的需求,也存在很多变通的方法,比如可以将需要进行事务管理的代码块独立为方法等。

2 Spring 注解 @Transactional

2.1 @Transactional 配置属性:

事务传播行为(Propagation)设置:

事务隔离级别(Isolation)设置:

事务隔离级别:定义了一个事务可能受其他并发事务影响的程度。

并发事务的常见问题:脏读(Dirty reads)— 事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据。

不可重复读(Nonrepeatable read)— 事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。(侧重 update)

幻读(Phantom read)— 系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。(侧重 insert和delete)注意:不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读问题只需锁住满足条件的行,解决幻读需要锁表。

readOnly 事务是否只读

读写事务:默认值。

只读事务:用于客户代码只读但不修改数据的情形,只读事务用于特定情景下的优化,比如使用Hibernate的时候。

timeout 事务超时

是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。

在 TransactionDefinition 中以 int 值来表示超时时间,其单位是:秒。

默认设置为:底层数据库的事务超时,如果底层数据库没有设置事务超时值,那么就是none没有超时限制。

Spring 事务回滚规则

事务回滚规则定义了哪些异常会导致事务回滚而哪些不会。

默认情况下:只有未检查异常(RuntimeException和Error类型异常)会导致事务回滚,而在遇到检查型异常时不会回滚。

定义事务回滚规则:可以声明事务遇到特定的检查型异常时,像遇到运行期异常那样回滚。也可以声明事务遇到特定的异常时,不回滚,即使这些异常是运行期异常。

2.2 @Transactional 添加规则:

1 @Transactional注解加在类或接口上,会对其中的所有的public方法都有效;加到方法上,则只在该方法起效;(推荐加在方法上)

2 @Transactional注解加在 private、protected 方法上是无效的,注解必须加在public方法上才有效;

3 添加了@Transactional注解的方法,在相互调用时,要明确 @Transactional 的作用范围:是使用不同的事务,还是沿用一开始的事务。参考:添加 @Transactional 函数之间相互调用时的作用效果,案例分析如下:

3.1 同一个类中方法之间的相互调用:

a 场景: aInnerFunc 抛异常, 则 aFunc 和 aInnerFunc 中的操作都回滚。

public class AClass {

@Transactional(rollbackFor = Exception.class)

public void aFunc() {

//todo: 数据库操作A(增,删,改) aInnerFunc(); // 调用内部没有添加@Transactional注解的函数 }

private void aInnerFunc() {

//todo: 操作数据B(做了增,删,改 操作) throw new RuntimeException("函数执行有异常!");

}

}

b 场景:等效于场景a 。

因为 aInnerFunc 是 private 方法,所以添加的 @Transactional 是无效的,两个函数依然使用同一个事务。

public class AClass {

@Transactional(rollbackFor = Exception.class)

public void aFunc() {

//todo: 数据库操作A(增,删,改) aInnerFunc(); // 调用内部没有添加@Transactional注解的函数 }

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

private void aInnerFunc() {

//todo: 操作数据B(做了增,删,改 操作) throw new RuntimeException("函数执行有异常!");

}

}

c 场景:aInnerFunc 抛异常,在 aFunc 中直接抓住异常;

public class AClass {

@Transactional(rollbackFor = Exception.class)

public void aFunc() {

//todo: 数据库操作A(增,删,改) try {

aInnerFunc(); // 调用内部没有添加@Transactional注解的函数 } catch (Exception e) {

e.printStackTrace();

}

}

private void aInnerFunc() {

//todo: 操作数据B(做了增,删,改 操作) throw new RuntimeException("函数执行有异常!");

}

}

3.2 不同类中方法之间的调用:

d 场景:bFunc抛异常,两个函数的操作都回滚了;

@Service()

public class AClass {

@Autowired

private BClass bClass;

@Transactional(rollbackFor = Exception.class)

public void aFunc() {

//todo: 数据库操作A(增,删,) bClass.bFunc();

}

}

@Service()

public class BClass {

public void bFunc() {

//todo: 数据库操作B(增,删,改) throw new RuntimeException("函数执行有异常!");

}

}

e场景:bFunc抛异常,两个函数对数据库的操作都回滚了;

aFunc 和 bFunc 都使用的 @Transactional(rollbackFor =Exception.class),表示 bFunc 和 aFunc 使用同一个事务,即便bFunc异常被抓住了,事务依然标记为回滚,所以两函数操作都回滚。

@Service()

public class AClass {

@Autowired

private BClass bClass;

@Transactional(rollbackFor = Exception.class)

public void aFunc() {

//todo: 数据库操作A(增,删,改) try {

bClass.bFunc();

} catch (Exception e) {

e.printStackTrace();

}

}

}

@Service()

public class BClass {

@Transactional(rollbackFor = Exception.class)

public void bFunc() {

//todo: 数据库操作B(增,删,改) throw new RuntimeException("函数执行有异常!");

}

}

f场景:bFunc抛异常,bFunc中的操作回滚,aFunc中的操作成功。

因为bFunc使用了propagation =Propagation.REQUIRES_NEW,表示bFunc使用一个新事务,这样aFunc和bFunc分别使用自己的事务;所以bFunc中的异常只引起自己方法内的回滚,不影响aFunc中的操作。

@Service()

public class AClass {

@Autowired

private BClass bClass;

@Transactional(rollbackFor = Exception.class)

public void aFunc() {

//todo: 数据库操作A(增,删,改) try {

bClass.bFunc();

} catch (Exception e) {

e.printStackTrace();

}

}

}

@Service()

public class BClass {

@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)

public void bFunc() {

//todo: 数据库操作B(增,删,改) throw new RuntimeException("函数执行有异常!");

}

}

参考

spring配置mysql事务管理_Spring 数据库事务管理机制相关推荐

  1. mysql dba系统学习-数据库事务详解

    mysql dba系统学习-数据库事务详解 上个星期去面试数据库管理员的工作,笔试通过之后就是直接的面试,他问了我一个问题,叫我介绍哈数据库的事务的看法和理解,但是不知所错的没有章法的乱答一气,唉唉, ...

  2. 数据库事务隔离级ORACLE数据库事务隔离级别介绍

    本文系转载,原文地址:http://singo107.iteye.com/blog/1175084 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted.Read committ ...

  3. 使用事务注解导致数据库事务一直在运行

    使用事务注解导致数据库事务一直在运行 1.问题出现原因: 场景: @Override//bcId 要选择的品牌对应bcid 不是头部的@Transactional(rollbackFor = Exce ...

  4. Spring事务管理--(一)数据库事务隔离级别与mysql引擎基础讲解

    一.前言 本篇文章来自网络整理,很简单,但是很实用对于初级和中级工程师. 原创地址1:http://www.cnblogs.com/hollen/archive/2012/05/13/2498309. ...

  5. Spring JDBC-Spring事务管理之数据库事务基础知识

    概述 数据库事务的概念 原子性 一致性 隔离性 持久性 数据并发的问题 脏读dirty read 不可重复读unrepeatable read 幻象读 phantom read 幻象读和不可重复度的区 ...

  6. Spring的事务管理和数据库事务相关知识

    1 初步理解 理解事务之前,先讲一个你日常生活中最常干的事:取钱.         比如你去ATM机取1000块钱,大体有两个步骤:首先输入密码金额,银行卡扣掉1000元钱:然后ATM出1000元钱. ...

  7. mysql事物日志工具,数据库事务日志 active

    Active Directory的脱机碎片整理,Active Directory系列之七 Active Directory的脱机碎片整理 Active Directory是一个被设计用于查询的非关系型 ...

  8. mysql事务并发控制_数据库 事务并发控制

    事务是一个逻辑工作单元, SQLServer 2005 提供了几种自动的可以通过编程来完成的机制,包括事务日志. SQL 事务控制语句,以及事务处理运行过程中通过锁定保证数据完整性的机制.当用户对数据 ...

  9. mysql 事务原子性_数据库事务原子性、一致性是怎样实现的?

    先借用前辈的一句话:数据库事务有不同的隔离级别,不同的隔离级别对锁的使用是不同的,锁的应用最终导致不同事务的隔离级别. 隔离性分为四个级别: 1读未提交:(Read Uncommitted) 2读已提 ...

最新文章

  1. 往往客户的需求是逐渐被深入的真正的实际需求往往没刚开始所说的那么简单容易就可以搞定...
  2. 2016视觉目标跟踪总结
  3. python当中的生成器
  4. java模拟atm 课程设计_急求,关于Java课程设计ATM创建实现
  5. 物理路径与虚拟路径 及Web Server
  6. OceanBase如何获得TPC-C测试第1名?
  7. idea for循环快捷键_IDEA骚技巧,编码速度至少快一倍
  8. 同一个项目的不同的项目工作经验总结--程序员丁
  9. 如何解决PHP上传中文出错,如何解决php上传中文乱码的问题
  10. linux用openssl制作自签名数字证书
  11. 吉他入门:吉他音阶训练入门教程(二)
  12. sql注入搞事情(连载一)
  13. 【2021 年终总结】一年涨粉100倍,有规划始执行~成功一半
  14. SDUT-程序设计基础-实验1-顺序结构
  15. 海思HI3751_HMS开发指南
  16. 【有利可图网】PS实战系列:用ps做出雨中油画的质感
  17. 51单片机控制动态数码管的显示
  18. 一文读懂什么是卡尔曼滤波
  19. CTF入门指南(0基础)
  20. Matlab之化简多项式

热门文章

  1. java的多态代码例子_java 多态实例代码
  2. python 图像的拉普拉斯变换中的数值问题_数字图像处理(第十章)
  3. java 祖父类_JAVA的XX.put中的put方法,是在哪个父类或祖父类中,详述父类链。
  4. 2 华为云闪付_教你区分信用卡刷卡、挥卡、插卡、云闪付等支付方式!
  5. 还是畅通工程(prim和kruskal)
  6. 面向对象设计原则与设计模式
  7. 自反而缩,虽千万人,吾往矣。
  8. 利用selenium模块配合chromedriver把html文件转换为图片
  9. application实现网页计数_手把手教你利用爬虫爬网页(Python代码)
  10. 如何控制if跳出_Wasm介绍之5:控制指令 | 火星技术帖