Spring:事务
摘要
本文摘抄了Spring事务相关的一些理论,主要讲述事务的特性、事务的传播行为、事务的隔离规则。
关键词:事务特性,事务传播,事务隔离
一、什么是事务
事务是用来保证数据的完整性和一致性,正如金钱转账,金钱总数不会增加也不会减少。
数据库 事务管理有四个特性(ACID):
特性 | 描述 |
---|---|
原子性(Atomicity) | 事务作为一个整体被执行,要么全部被执行,要么都不执行。 |
一致性(Consistency) | 事务应确保数据的状态从一个一致状态转变为另一个一致状态,数据不应该被破坏。 |
隔离性(Isolation) | 多个事务并发执行时,一个事务的执行不应影响其他事务的执行。 |
持久性(Durability) | 已被提交的事务对数据的修改应该永久性的。 |
二、Spring事务管理器
1. 事务管理接口
Spring中定义了事务管理的总接口PlatformTransactionManager,该接口定义了以下几个接口来管理事务:
- getTransaction() - 获取事务状态(TransactionStatus),该事务由(TransactionDefinition定义)
- commit() - 提交事务
- rollback() - 回滚事务
Spring不直接管理事务,而是提供一个事务管理接口,由其他平台(如JDBC、Hibernate)自己实现事务管理。
几个具体的事务:
事务名称 | 管理器类 | 说明 |
---|---|---|
JDBC事务 | org.springframework.jdbc.datasource.DataSourceTransactionManager | 通过调用java.sql.Connection来管理事务 |
Hibernate | org.springframework.orm.hibernate3.HibernateTransactionManager | 事务管理由org.hibernate.Transaction对象负责 |
Java持久化API事务(JPA) | org.springframework.orm.jpa.JpaTransactionManager | JpaTransactionManager与由工厂(javax.persistence.EntityManagerFactory)所产生的JPA EntityManager合作来构建事务 |
Java原生API事务 | org.springframework.transaction.jta.JtaTransactionManager | JtaTransactionManager将事务管理的责任委托给javax.transaction.UserTransaction和javax.transaction.TransactionManager对象(允许在多个数据库之间管理多个事务) |
关于JTA,参考Java中的事务——JDBC事务和JTA事务
(Spring事务管理器)
2. 事务管理与AOP
Spring通过AOP拦截所有需要事务管理的业务处理方法。
三、Spring事务属性
Spring事务有几个属性,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. 传播行为
所谓传播行为(propagation behavior)指一个事务方法被另一个事务方法调用时,事务应该如何处理。被调用的方法可能在现有事务中运行,或者启动一个新的事务,在自己事务内运行。
传播行为 | 含义 | 解释 |
---|---|---|
PROPAGATION_REQUIRED | 表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务 | 有且只有一个事务 |
PROPAGATION_SUPPORTS | 表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行 | 如果方法单独调用则是非事务执行,如果方法被另一个有事务的方法调用,被调用方法则加入事务 |
PROPAGATION_MANDATORY | 表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常 | 如果单独非事务调用会抛异常,必须被其它事务方法调用,加入到事务中。 |
PROPAGATION_REQUIRED_NEW | 表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。如果存在当前事务,在该方法执行期间,当前事务会被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager | 总是开启一个新的事务,原调用事务存在的话会被挂起,直至事务完成。 |
PROPAGATION_NOT_SUPPORTED | 表示该方法不应该运行在事务中。如果存在当前事务,在该方法运行期间,当前事务将被挂起。如果使用JTATransactionManager的话,则需要访问TransactionManager | 总是非事务地执行该方法,如果调用事务存在的话会被挂起,直至方法执行完成 |
PROPAGATION_NEVER | 表示当前方法不应该运行在事务上下文中。如果当前正有一个事务在运行,则会抛出异常 | 总是非事务性执行方法,否则抛出异常 |
PROPAGATION_NESTED | 表示如果当前已经存在一个事务,那么该方法将会在嵌套事务中运行。嵌套的事务可以独立于当前事务进行单独地提交或回滚。如果当前事务不存在,那么其行为与PROPAGATION_REQUIRED一样。注意各厂商对这种传播行为的支持是有所差异的。可以参考资源管理器的文档来确认它们是否支持嵌套事务 | 嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。 |
2. 隔离规则
事务的执行会存在并发的,隔离级别定义了一个事务受其它并发事务影响的程度。
有两个表格:
并发事务引起的问题
问题 | 定义 | 出现原因 |
---|---|---|
脏读 | 读到无效的数据 | 当一个事务读取了另一个事务修改但未提交的数据,如果修改回滚,则事务读取了无效的数据。 |
不可重复读 | 同一个事务中两次相同查询中,读取到不同的数据 | 一个事务两次查询期间,另一个并发事务对数据进行了更新。 |
幻读 | 同一个事务在两次相同的查询中,读取到不同记录数的数据 | 一个事务两次查询期间,另一个并发事务进行了数据新增或删除。 |
隔离级别
隔离级别 | 说明 | 并发事务可能引起的问题 |
---|---|---|
ISOLATION_DEFAULT | 使用后端数据库默认的隔离级别 | 具体情况具体分析 |
ISOLATION_READ_UNCOMMITTED | 最低的隔离级别,允许读取尚未提交的数据变更 | 脏读、不可重复读、幻读 |
ISOLATION_READ_COMMITTED | 允许读取并发事务已经提交的数据 | 不可重复读、幻读 |
ISOLATION_REPEATABLE_READ | 对同一字段的多次读取结果一致,除非字段被本事务修改 | 幻读 |
ISOLATION_SERIALIZABLE | 最高的隔离级别,完全服从ACID原则,通常通过锁表实现(最慢) | 无 |
3. 事务超时
给定事务一个超时时间,如果特定时间事务没有执行完毕,事务会自动回滚。
4. 是否只读?
设置了只读事务,那么在此事务执行过程中,其它事务对数据库的修改对于该事务来说是透明的,即看不到其它事务修改后的数据。这通常用于执行多次查询来统计信息时,能够保证数据的整体一致性。
5. 回滚规则
回滚规则定义了哪些异常,事务会进行回滚。默认情况下,事务只有遇到运行时异常才会回滚,而在遇到检查型异常时不会回滚。
四、Spring事务管理形式
1. 编程式事务
使用TransactionTemplate或PlatformTransactionManager
TransactionTemplate tt = new TransactionTemplate();
tt.execute(status -> {
// 执行操作
doSth();
// 返回操作结果
return obj;
});
2. 声明式事务
六、总结
- Spring定义了事务管理器的接口,具体实现由特定平台来实现;
- Spring事务有五个属性:事务传播行为、事务隔离级别、事务超时、事务只读、回滚规则;
- 传播行为:required、supports、mandatory、required_new、not_support、never、nested;
- 隔离级别:default、read_uncommited、read_committed、repeatable_read、serializable;
参考资料
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 ...
随机推荐
- Android Studio 1.0~3.3加载android源码 笔记
一. AS3.3上出现问题: 1. File Z:\Project\****\***\AndroidManifest.xml doesnt exist 分析引用: ------------------ ...
- 20175311 2018-2019-2 《Java程序设计》第四周学习总结
20175311 2018-2019-2 <Java程序设计>第4周学习总结 教材学习内容总结 这一周在上一周的基础上更进一步,主要学习了子类的继承.super关键字的用法含义.继承与多态 ...
- Spring AOP Capabilities and Goal
Spring AOP是用纯的java实现的.不需要任何个性的实现过程.Spring AOP不需要控制类加载器,并且它适用于Servlet容器或者应用服务器. Spring AOP当前只支持方法执行的连 ...
- 删除N天前的文件(夹)与拷贝文件到共享盘的批处理
rem ======= 删除目录 7天前目录 ========= forfiles /P "E:\Folder" /S /D -7 /C "Cmd /C If @isdi ...
- 使用aliyun cli工具快速创建云主机
参考文档: https://help.aliyun.com/document_detail/25484.html?spm=a2c4g.11186623.3.2.b57vQp 步骤 创建AccessID ...
- To be taught if i am fortunate
此博客算是我自娱自乐的海洋球池吧. 由于我十分的菜并且文笔拙劣,所以您可能并不能在这找到什么有用的信息或者好玩的东西(或者exciting的内容). 如果您能指出我的一些错误,我将十分感激.
- redis集群报错:(error) CLUSTERDOWN Hash slot not served
百度上坑太多,如果你遇到搭建redis集群的时候出现这个错误在百度上找到解决办法基本上都是坑. 首先集群搭建完成后,你肯定去登陆redis进行测试 1.redis01/redis-cli -h &qu ...
- java封装的概念学习笔记
继承.封装.多态.抽象是面向对象编程的四大基本概念,其中封装装为重要,因为从我们学习JAVA开始,就基本上接触了封装,因为JAVA中的所有程序都是写在类中的,类也能当做一种封装. 在面向对象中封装 ...
- samba、ftp和ssh服务
samba服务 Smb主要作为网络通信协议; Smb是基于cs架构: 完成Linux与windows之间的共享:linux与linux之间共享用NFS 第一步:安装samba [root@ken ~] ...
- 使用 Angular Console 提升开发体验
Angular Console Angular Console 是一个用于扩展 Angular CLI 的强大工具,通过提供一个图形界面的形式,方便开发者使用 CLI 的功能. Angular CLI ...