【Spring】事务
一、数据库事务概述
- 事务:是逻辑上一组操作,要么全都成功,要么全都失败.
事务特性: (ACID)
- 原子性:事务不可分割
- 一致性:事务执行的前后,数据完整性保持一致.
- 隔离性:一个事务执行的时候,不应该受到其他事务的打扰
- 持久性:一旦结束,数据就永久的保存到数据库.
如果不考虑隔离性会出现如下问题:
- 脏读:一个事务读到另一个事务未提交数据
- 不可重复读:一个事务读到另一个事务已经提交数据(update)导致一个事务多次查询结果不一致
- 虚读:一个事务读到另一个事务已经提交数据(insert)导致一个事务多次查询结果不一致
事务的隔离级别:
- 未提交读:以上情况都有可能发生。
- 已提交读:避免脏读,但不可重复读,虚读是有可能发生。
- 可重复读:避免脏读,不可重复读,但是虚读有可能发生。
- 串行的:避免以上所有情况.
关于事务的详细内容可以查阅:【DataBase】事务
二、Spring中事务
1. Spring 事务管理:
分层开发:事务处在Service层.
2. Spring 事务管理的API:
2.1 API概述
PlatformTransactionManager:平台事务管理器,定义了如下方法:
Public interface PlatformTransactionManager()...{
// Return a currently active transaction or create a new one, according to the specified propagation behavior(根据指定的传播行为,返回当前活动的事务或创建一个新事务。)
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
// Commit the given transaction, with regard to its status(使用事务目前的状态提交事务)
Void commit(TransactionStatus status) throws TransactionException;
// Perform a rollback of the given transaction(对执行的事务进行回滚)
Void rollback(TransactionStatus status) throws TransactionException;
}
TransactionDefinition:事务定义信息
- ISOLation_XXX:事务隔离级别
- PROPAGATION_XXX:事务的传播行为
- 过期时间等
TransactionStatus:事务的状态
- 是否有保存点
- 是否一个新的事务
- 事务是否已经提交
- 上述接口之间的关系
PlatformTransactionManager通过TransactionDefinition设置事务相关信息管理事务,管理事务过程中,产生一些事务状态:状态由TransactionStatus记录.
2.2 PlatformTransactionManager 接口
Spring为不同的持久化框架提供了不同PlatformTransactionManager接口实现 :
org.springframework.jdbc.datasource.DataSourceTransactionManager:使用Spring JDBC或Mybatis 进行持久化数据时使用org.springframework.orm.hibernate3.HibernateTransactionManager:使用Hibernate3.0版本进行持久化数据时使用org.springframework.orm.jpa.JpaTransactionManager:使用JPA进行持久化时使用org.springframework.jdo.JdoTransactionManager:当持久化机制是Jdo时使用org.springframework.transaction.jta.JtaTransactionManager:使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用
如果我们在使用JDBC或者Mybatis进行数据持久化操作时,我们的XML配置通常如下:
<!-- 事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>
2.3 TransactionDefinition 接口
事务管理器接口 PlatformTransactionManager 通过 getTransaction(TransactionDefinition definition) 方法来得到一个事务,这个方法里面的参数是 TransactionDefinition类 ,
这个类就定义了一些基本的事务属性。(隔离级别、传播行为、回滚规则、是否只读、事务超时)
public interface TransactionDefinition {
//传播行为
int PROPAGATION_REQUIRED = 0;
int PROPAGATION_SUPPORTS = 1;
int PROPAGATION_MANDATORY = 2;
int PROPAGATION_REQUIRES_NEW = 3;
int PROPAGATION_NOT_SUPPORTED = 4;
int PROPAGATION_NEVER = 5;
int PROPAGATION_NESTED = 6;
//隔离级别
int ISOLATION_DEFAULT = -1;
int ISOLATION_READ_UNCOMMITTED = Connection.TRANSACTION_READ_UNCOMMITTED;
int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
int ISOLATION_REPEATABLE_READ = Connection.TRANSACTION_REPEATABLE_READ;
int ISOLATION_SERIALIZABLE = Connection.TRANSACTION_SERIALIZABLE;
int TIMEOUT_DEFAULT = -1;
//方法
int getPropagationBehavior();
int getIsolationLevel();
int getTimeout();
boolean isReadOnly();
String getName();
}
(1) 隔离级别
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
ISOLATION_DEFAULT:默认的隔离级别. MySQL:
repeatable_read,Oracle:read_commitedISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。
ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。
(2) 事务的传播行为
事务的传播行为:不是JDBC事务管理,是用来解决实际开发的问题,解决业务层之间的调用的事务的关系.


支持当前事务
- ⭐️PROPAGATION_REQUIRED:支持当前事务,如果不存在 就新建一个
- A,B 如果A有事务,B使用A的事务,如果A没有事务,B就开启一个新的事务.(A,B是在一个事务中。)
- PROPAGATION_SUPPORTS :支持当前事务,如果不存在,就不使用事务
- A,B 如果A有事务,B使用A的事务,如果A没有事务,B就不使用事务.
- PROPAGATION_MANDATORY:支持当前事务,如果不存在,抛出异常
- A,B 如果A有事务,B使用A的事务,如果A没有事务,抛出异常.
不支持当前事务
- ⭐️PROPAGATION_REQUIRES_NEW:不支持当前事务,如果有事务存在,挂起当前事务,创建一个新的事务
- A,B 如果A有事务,B将A的事务挂起,重新创建一个新的事务.(A,B不在一个事务中.事务互不影响.)
- PROPAGATION_NOT_SUPPORTED:不支持当前事务,以非事务方式运行,如果有事务存在,挂起当前事务
- A,B 非事务的方式运行,A有事务,就会挂起当前的事务.
- PROPAGATION_NEVER:不支持当前事务,以非事务方式运行,如果有事务存在,抛出异常
其他(Spring 所特有的)
- ⭐️PROPAGATION_NESTED:如果当前事务存在,则嵌套事务执行
- 基于SavePoint技术.
- A,B A有事务,A执行之后,将A事务执行之后的内容保存到SavePoint.B事务有异常的话,用户需要自己设置事务提交还是回滚.
- 基于SavePoint技术.
(3) 事务超时属性(一个事务允许执行的最长时间)
所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。
(4) 事务只读(对事物资源是否执行只读操作)
事务的只读属性是指,对事务性资源进行只读操作或者是读写操作。所谓事务性资源就是指那些被事务管理的资源,比如数据源、 JMS 资源,以及自定义的事务性资源等等。如果确定只对事务性资源进行只读操作,那么我们可以将事务标志为只读的,以提高事务处理的性能。在 TransactionDefinition 中以 boolean 类型来表示该事务是否只读。
(5) 回滚规则(定义事务回滚规则)
这些规则定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚(这一行为与EJB的回滚行为是一致的)。但是你可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。同样,你还可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。
2.4 TransactionStatus 接口
TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息.
PlatformTransactionManager.getTransaction(…) 方法返回一个TransactionStatus 对象。返回的TransactionStatus 对象可能代表一个新的或已经存在的事务(如果在当前调用堆栈有一个符合条件的事务)。TransactionStatus接口接口内容如下:
public interface TransactionStatus{
boolean isNewTransaction(); // 是否是新的事物
boolean hasSavepoint(); // 是否有恢复点
void setRollbackOnly(); // 设置为只回滚
boolean isRollbackOnly(); // 是否为只回滚
boolean isCompleted; // 是否已完成
}
三、Spring 事务实战
声明式事务、编程式事务
【Spring】事务的更多相关文章
- spring事务概念理解
1.数据并发问题 脏读 A事务读取B事务尚未提交的更新数据,并在此数据的基础上操作.如果B事务回滚,则A事务读取的数据就是错误的.即读取了脏数据或者错误数据. 不可重复组 A事务先后读取了B事务提交[ ...
- 【Java EE 学习 52】【Spring学习第四天】【Spring与JDBC】【JdbcTemplate创建的三种方式】【Spring事务管理】【事务中使用dbutils则回滚失败!!!??】
一.JDBC编程特点 静态代码+动态变量=JDBC编程. 静态代码:比如所有的数据库连接池 都实现了DataSource接口,都实现了Connection接口. 动态变量:用户名.密码.连接的数据库. ...
- Spring事务
1.@Transactional 只能被应用到public方法上, 对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.@Transactional 的 ...
- spring事务管理器设计思想(二)
上文见<spring事务管理器设计思想(一)> 对于第二个问题,涉及到事务的传播级别,定义如下: PROPAGATION_REQUIRED-- 如果当前没有事务,就新建一个事务.这是最常见 ...
- spring事务管理器设计思想(一)
在最近做的一个项目里面,涉及到多数据源的操作,比较特殊的是,这多个数据库的表结构完全相同,由于我们使用的ibatis框架作为持久化层,为了防止每一个数据源都配置一套规则,所以重新实现了数据源,根据线程 ...
- Spring事务管理的三种方式
一 .第一种:全注解声明式事务 Xml代码 复制代码 收藏代码 .<?xml version="1.0" encoding="UTF-8"?> .& ...
- spring 事务传播特性 和隔离级别
事务的几种传播特性1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务.如果没有事务则开启2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务 ...
- Spring事务管理
Spring是SSH中的管理员,负责管理其它框架,协调各个部分的工作.今天一起学习一下Spring的事务管理.Spring的事务管理分为声明式跟编程式.声明式就是在Spring的配置文件中进行相关配置 ...
- Spring事务传播属性
Spring 对事务控制的支持统一在 TransactionDefinition 类中描述,该类有以下几个重要的接口方法: int getPropagationBehavior():事务的传播行为 i ...
- Spring事务属性的介绍
Spring声明式事务让我们从复杂的事务处理中得到解脱.使得我们再也无需要去处理获得连接.关闭连接.事务提交和回滚等这些操作.再也无需要我们在与事务相关的方法中处理大量的try-catch-final ...
随机推荐
- python3 编译安装
前言: Linux下大部分系统默认自带python2.x的版本,最常见的是python2.6或python2.7版本,默认的python被系统很多程序所依赖,比如centos下的yum就是python ...
- java虚拟机学习笔记(六)---垃圾收集算法
主要讨论集中垃圾收集算法的思想及发展过程. 1.标记-清除法 最基础的收集算法是标记-清除法,算法分为标记和清除两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象,其标记过程 ...
- 纯前端下载pdf链接文件,而不是打开预览的解决方案
纯前端下载pdf链接文件,而不是打开预览的解决方案 一,介绍与需求 1.1,介绍 XMLHttpRequest 用于在后台与服务器交换数据.这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行 ...
- APP手机商城系统选择,混合开发与原生开发哪个好?
关于手机APP开发用混合还是原生现在说法不一,有说混合开发好:时间短.费用低.效果也不错,有说原生开发好,原生APP在性能方面比较好.而商城系统中的手机APP用混合开发还是原生开发比较好呢? 最近我参 ...
- zabbix利用自带模板-监控mysql性能
环境: zabbix3.4.4 mariadb 5.5.56 要求: 利用zabbix 自带的模板 监控mariadb 上的 并发连接数,慢查询数量,增删改查.请求流量带宽,mysql响应流量带宽等 ...
- Windows 10“数字权利激活”永久性激活!!!
直接运行软件即可自动激活,等出现"激活成功"即可关闭软件. 注意事项: 激活软件不会帮你打开Windows update服务,如关闭系统自动更细服务的需要先启动服务. 可以在小娜搜 ...
- 2015-11-13 linux基础笔记
1.安装linux 使用光盘,版本CENSOS6.6 2.命令过长请使用\ 后enter键换行转义 直到不需要转义后回车运行 3.linux 大小写敏感 4.显示terminal 输出语言 ec ...
- MinorGC和FullGC的触发条件
前言 无论是日常工作,还是企业面试,我们都会经常接触到GC.我们都知道GC是java中的垃圾回收策略.GC帮我们省去了很多事.在GC中,我经常听到的就属于MinorGC和FullGC了.那么在什么情况 ...
- .Net Core 三大Redis客户端对比和使用心得
前言 稍微复杂一点的互联网项目,技术选型都可能会涉及Redis,.NetCore的生态越发完善,支持.NetCore的Redis客户端越来越多, 下面三款常见的Redis客户端,相信大家平时或多或少用 ...
- Spring学习之旅(七)--SpringMVC视图
在之前的实例中我们只是在 Controller 中返回了 home 字符类型的值,而没有直接生成可以在浏览器中直接渲染的 HTML,这是因为 SpringMVC 将请求处理的逻辑和视图渲染的实现进行了 ...