当前位置: 首页 > news >正文

Spring声明式事务管理之一:五大属性分析

1.Spring事务管理概述

  Spring事务管理分为编程式事务管理和声明式事务管理两种。
编程式事务允许用户在实现代码中使用显式的方式调用beginTransaction()开启事务、commit()提交事务、rollback()回滚事务,从而可以达到精确定义事务的边界。
声明式事务管理底层是建立在Spring AOP的基础上,在方式执行前后进行拦截,并在目标方法开始执行前创建新事务或加入一个已存在事务,最后在目标方法执行完后根据情况提交或者回滚事务。声明式事务的最大优点就是不需要编程,将事务管理从复杂业务逻辑中抽离,只需要在配置文件中配置并在目标方法上添加@Transactional注解即可实现。
Spring事务属性定义在TransactionDefinition接口中,Spring4中该接口代码实现如下:

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 = 1;
    int ISOLATION_READ_COMMITTED = 2;
    int ISOLATION_REPEATABLE_READ = 4;
    int ISOLATION_SERIALIZABLE = 8;
    int TIMEOUT_DEFAULT = -1;
    //事务的传播行为
    int getPropagationBehavior();
    //事务的隔离级别
    int getIsolationLevel();
    //事务超时时间
    int getTimeout();
    //是否只读
    boolean isReadOnly();
    String getName();
}

Spring事务属性可以就是事务的一些基本配置,描述了事务策略如何应用到方法上面,事务属性包含以下5个方面:
Spring事务五大属性

2.Spring事务的传播属性  

Spring事务传播属性有7种:在事务定义接口TransactionDefinition中定义了7个表示传播行为的常量,分别是

PROPAGATION_REQUIRED;
PROPAGATION_SUPPORTS;
PROPAGATION_MANDATORY;
PROPAGATION_REQUIRES_NEW;
PROPAGATION_NOT_SUPPORTED; 
PROPAGATION_NEVER;
PROPAGATION_NESTED;

在方法@Transactional注解时使用如下:
@Transactional(propagation=Propagation.REQUIRED) 如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
@Transactional(propagation=Propagation.NOT_SUPPORTED)容器不为这个方法开启事务@Transactional(propagation=Propagation.REQUIRES_NEW)不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行旧的事务
@Transactional(propagation=Propagation.MANDATORY)必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.NEVER) 必须在一个没有的事务执行,否则抛出异常(与Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS)如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他  bean没有声明事务,那就不用事务.
详细描述如下表所示:
@Transactional注解

3.Spring事务的隔离级别

Spring事务的隔离级别定义了一个事务可能受到其他并发事务影响的程度,在事务定义接口TransactionDefinition 中定义了五个表示隔离级别的常量,分别是

ISOLATION_DEFAULT,
ISOLATION_READ_UNCOMMITTED,
ISOLATION_READ_COMMITTED,
ISOLATION_REPEATABLE_READ, 
ISOLATION_SERIALIZABLE;

各个隔离级别在Spring中注解方式如下:
@Transactional(isolation = Isolation.READ_UNCOMMITTED)读取未提交数据(会出现脏读, 不可重复读) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED)读取已提交数据(会出现不可重复读和幻读)
@Transactional(isolation = Isolation.REPEATABLE_READ)可重复读(会出现幻读)
@Transactional(isolation = Isolation.SERIALIZABLE)串行化
@Transactional(isolation = Isolation.DEFAULT)默认级别,MYSQL: 默认为REPEATABLE_READ级别 SQLSERVER: 默认为READ_COMMITTED
隔离级别详细描述如下表
Spring事务隔离级别

4.Spring事务超时时间

TransactionDefinition 接口中定义了1个表示超时时间的常量TIMEOUT_DEFAULT ,使用getTimeout()方法可以获取到超时时间,单位是秒。Spring事务超时时间,是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。
在Spring程序中超时时间设置的注解方式是设置timeout的值表示这个事务,true只读取数据但不更新数据,false表示可正常读写数据
@Transactional(timeout=30) 默认是-1,不超时
超时时间详细描述如下表
超时时间

5.Spring事务是否只读

事务管理的只读属性是指对事务性资源进行只读操作或者是可读写操作。所谓事务性资源就是指那些被事务管理的资源,如数据源、JMS 资源,以及自定义的事务性资源等。如果确定只对事务性资源进行只读操作,那么我们可以将事务标志为只读的,以提高事务处理的性能。在TransactionDefinition 中以 boolean 类型来表示该事务是否只读,使用方法isReadOnly()来判断事务是否是只读的。
事务管理的只读属性详细描述如下
事务管理的只读属性

6.Spring事务回滚规则

通常情况下,如果在事务中抛出了未检查异常(继承自 RuntimeException 的异常),则默认将回滚事务。如果没有抛出任何异常,或者抛出了已检查异常,则正常提交事务。我们可以根据需要人为控制事务在抛出某些未检查异常时仍然提交事务,或者在抛出某些已检查异常时回滚事务。
Transactional注解中有4个属性通过设置系统异常类和自定义异常类来自定义回滚规则。
4个属性分别是

rollbackFor,
rollbackForClassName,
noRollbackFor,
noRollbackForClassName

@Transactional(rollbackFor=RuntimeException.class)
用于设置需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,则事务回滚。
@Transactional(rollbackForClassName="RuntimeException")
用于设置需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,则进行事务回滚
@Transactional(noRollbackFor=RuntimeException.class)
用于设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚
@Transactional(noRollbackForClassName=RuntimeException.class)
用于设置不需要进行回滚的异常类名称数组,当方法中抛出指定异常名称数组中的异常时,不进行事务回滚
Spring事务回滚规则

7.@Transactional注解常用参数

在Spring开发中,@Transactional注解的常用参数汇总如下
@Transactional注解常用参数 

本订阅号提供Java相关技术分享,从Java编程基础到Java高级技术,从JavaWeb技术基础Jsp、Servlet、JDBC到SSH、SSM开发框架,从REST风格接口设计到分布式项目实战。剖析主流开源技术框架,用亲身实践来谱写深度Java技术日志。“

欢迎关注 Java技术日志 微信订阅号

相关文章:

  • 解决Activity启动黑屏及设置android:windowIsTranslucent不兼容activity切换动画问题
  • UWP Popup 弹出提示框
  • 利用Dawn工程化工具实践MobX数据流管理方案
  • crontab_定时执行任务(python)
  • 【commons-io】File对文件与目录的处理FileUtis,IOUtils,FilenameUtils工具的使用
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
  • vue2组件之间双向数据绑定问题
  • IO(字节流、字符流)
  • Linux环境安装docker
  • 康复者的福音来了,只要穿上这款机器人外骨骼便能自由转身
  • Linux系统的数据写入机制--延迟写入
  • 它改变了整个扫地机器人行业,如今被全面收购
  • Day16 Django
  • Paros proxy:网页程序漏洞评估代理
  • HTML 5 Web 存储-sessionStorage和localStorage
  • 【附node操作实例】redis简明入门系列—字符串类型
  • 08.Android之View事件问题
  • bearychat的java client
  • Fabric架构演变之路
  • happypack两次报错的问题
  • Js基础知识(一) - 变量
  • 聚类分析——Kmeans
  • 想晋级高级工程师只知道表面是不够的!Git内部原理介绍
  • 新书推荐|Windows黑客编程技术详解
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • ​queue --- 一个同步的队列类​
  • !!java web学习笔记(一到五)
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #stm32驱动外设模块总结w5500模块
  • (1) caustics\
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .NET MAUI学习笔记——2.构建第一个程序_初级篇
  • .NET 指南:抽象化实现的基类
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • @media screen 针对不同移动设备
  • [ C++ ] STL---string类的使用指南
  • [].shift.call( arguments ) 和 [].slice.call( arguments )
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——
  • [Android]一个简单使用Handler做Timer的例子
  • [BZOJ4016][FJOI2014]最短路径树问题
  • [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)
  • [C++11 多线程同步] --- 条件变量的那些坑【条件变量信号丢失和条件变量虚假唤醒(spurious wakeup)】
  • [Excel]如何找到非固定空白格數列的條件數據? 以月份報價表單為例
  • [HTML]Web前端开发技术28(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页
  • [IE编程] IE中使网页元素进入编辑模式
  • [LeetCode][LCR190]加密运算——全加器的实现
  • [MySQL复制异常]Cannot execute statement: impossible to write to binary log since statement is in row for
  • [Oh My C++ Diary]用cout输出流保留输出小数位数的方法
  • [PHP] 算法-顺时针打印矩阵的PHP实现
  • [POJ2104]K-th Number