Java——Spring事务属性、事务传播行为

掌握Java动态代理在事务管理中的应用 面向切面编程(Aspect-Oriented Programming, AOP)是一种编程范式,旨在将横切关注点(cross-cutting concerns)从业务逻辑代码中分离出来,以提高模块化。通过AOP,开发者可以将诸如日志、事务管理、安全检查等非核心业务逻辑集中管理和实现,而不需要修改业务逻辑代码本身。AOP的核心概念包括:切面(Aspect):切面是横切关注点的模块化,比如一个日志切面可以包含日志记录的方法和通知(Advice)。连接点(Join Point) 阅读详情

一、事务配置

上面这些属性都可以在 @Transactional 注解的参数上进行设置。

  • readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true。

  • timeout:设置超时时间单位秒,在多长时间之内事务没有提交成功就自动回滚,-1表示不设置超时时间。

  • rollbackFor:当出现指定异常进行事务回滚

  • noRollbackFor:当出现指定异常不进行事务回滚

    • 思考:出现异常事务会自动回滚,这个是我们之前就已经知道的

    • noRollbackFor是设定对于指定的异常不回滚,这个好理解

    • rollbackFor是指定回滚异常,对于异常事务不应该都回滚么,为什么还要指定?

      • 这块需要更正一个地方,并不是所有的异常都会回滚事务,比如下面的代码就不会回滚
            <pre class="prettyprint hljs groovy" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">public interface AccountService {
                /**
                 * 转账操作
                 * @param out 传出方
                 * @param in 转入方
                 * @param money 金额
                 */
                //配置当前接口方法具有事务
                public void transfer(String out,String in ,Double money) throws IOException;
            }
            
            @Service
            public class AccountServiceImpl implements AccountService {
            
                @Autowired
                private AccountDao accountDao;
                @Transactional
                public void transfer(String out,String in ,Double money) throws IOException{
                    accountDao.outMoney(out,money);
                    //int i = 1/0; //这个异常事务会回滚
                    if(true){
                        throw new IOException(); //这个异常事务就不会回滚
                    }
                    accountDao.inMoney(in,money);
                }
            
            }
  • 出现这个问题的原因是,Spring的事务只会对 Error异常 和 RuntimeException异常 及其子类进行事务回顾,其他的异常类型是不会回滚的,对应IOException不符合上述条件所以不回滚

    • 此时就可以使用rollbackFor属性来设置出现IOException异常不回滚
        <pre class="prettyprint hljs groovy" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">@Service
        public class AccountServiceImpl implements AccountService {
        
            @Autowired
            private AccountDao accountDao;
             @Transactional(rollbackFor = {IOException.class})
            public void transfer(String out,String in ,Double money) throws IOException{
                accountDao.outMoney(out,money);
                //int i = 1/0; //这个异常事务会回滚
                if(true){
                    throw new IOException(); //这个异常事务就不会回滚
                }
                accountDao.inMoney(in,money);
            }
        
        }
  • rollbackForClassName等同于rollbackFor,只不过属性为异常的类全名字符串

  • noRollbackForClassName等同于noRollbackFor,只不过属性为异常的类全名字符串

  • isolation设置事务的隔离级别

    • DEFAULT :默认隔离级别, 会采用数据库的隔离级别

    • READ_UNCOMMITTED : 读未提交

    • READ_COMMITTED : 读已提交

    • REPEATABLE_READ : 重复读取

    • SERIALIZABLE: 串行化

介绍完上述属性后,还有一个事务的传播行为,先看下面的案例

二、转账业务追加日志案例

2.1 需求分析

  • 需求:实现任意两个账户间转账操作,并对每次转账操作在数据库进行留痕

  • 需求微缩:A账户减钱,B账户加钱,数据库记录日志

基于上述的业务需求,我们来分析下该如何实现:

①:基于转账操作案例添加日志模块,实现数据库中记录日志

②:业务层转账操作(transfer),调用减钱、加钱与记录日志功能

需要注意一点就是,我们这个案例的预期效果为:

无论转账操作是否成功,均进行转账操作的日志留痕

2.2 环境准备

步骤1:创建日志表

<pre class="prettyprint hljs sql" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">create table tbl_log(
   id int primary key auto_increment,
   info varchar(255),
   createDate datetime
)

步骤2:添加LogDao接口

<pre class="prettyprint hljs java" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">public interface LogDao {
    @Insert("insert into tbl_log (info,createDate) values(#{info},now())")
    void log(String info);
}

步骤3:添加LogService接口与实现类

<pre class="prettyprint hljs kotlin" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">public interface LogService {
    void log(String out, String in, Double money);
}
@Service
public class LogServiceImpl implements LogService {

    @Autowired
    private LogDao logDao;
    @Transactional
    public void log(String out,String in,Double money ) {
        logDao.log("转账操作由"+out+"到"+in+",金额:"+money);
    }
}

步骤4:在转账的业务中添加记录日志

<pre class="prettyprint hljs kotlin" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">public interface AccountService {
    /**
     * 转账操作
     * @param out 传出方
     * @param in 转入方
     * @param money 金额
     */
    //配置当前接口方法具有事务
    public void transfer(String out,String in ,Double money)throws IOException ;
}
@Service
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;
    @Autowired
    private LogService logService;
    @Transactional
    public void transfer(String out,String in ,Double money) {
        try{
            accountDao.outMoney(out,money);
            accountDao.inMoney(in,money);
        }finally {
            logService.log(out,in,money);
        }
    }

}

步骤5:运行程序

  • 当程序正常运行,tbl_account表中转账成功,tbl_log表中日志记录成功

  • 当转账业务之间出现异常(int i =1/0),转账失败,tbl_account成功回滚,但是tbl_log表未添加数据

  • 这个结果和我们想要的不一样,什么原因?该如何解决?

  • 失败原因:日志的记录与转账操作隶属同一个事务,同成功同失败

  • 最终效果:无论转账操作是否成功,日志必须保留

三、事务传播行为

对于上述案例的分析:

  • log方法、inMoney方法和outMoney方法都属于增删改,分别有事务T1,T2,T3

  • transfer因为加了@Transactional注解,也开启了事务T

  • 前面我们讲过Spring事务会把T1,T2,T3都加入到事务T中

  • 所以当转账失败后,所有的事务都回滚,导致日志没有记录下来

  • 这和我们的需求不符,这个时候我们就想能不能让log方法单独是一个事务呢?

要想解决这个问题,就需要用到事务传播行为,所谓的事务传播行为指的是:

事务传播行为:事务协调员对事务管理员所携带事务的处理态度。

具体如何解决,就需要用到之前我们没有说的 propagation属性 。

1.修改logService改变事务的传播行为

<pre class="prettyprint hljs kotlin" style="padding: 0.5em; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace; color: rgb(68, 68, 68); border-radius: 4px; display: block; margin: 0px 0px 1.5em; font-size: 14px; line-height: 1.5em; word-break: break-all; overflow-wrap: break-word; white-space: pre; background-color: rgb(246, 246, 246); border: none; overflow-x: auto;">@Service
public class LogServiceImpl implements LogService {

    @Autowired
    private LogDao logDao;
    //propagation设置事务属性:传播行为设置为当前操作需要新事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void log(String out,String in,Double money ) {
        logDao.log("转账操作由"+out+"到"+in+",金额:"+money);
    }
}</pre>

运行后,就能实现我们想要的结果,不管转账是否成功,都会记录日志。

2.事务传播行为的可选值

ANSYS入门学习方法:从单元选择到后处理的完整分析链路 有限元分析(FEA)是工程仿真核心,ANSYS作为主流工具,其学习关键在于理解单元类型、材料模型与网格划分的底层逻辑。单元选择决定材料兼容性,如Solid65专用于混凝土非线性分析;网格划分中六面体优于四面体,影响收敛与精度。掌握这些原理可避免常见错误,提升结构分析效率。适用于土木、机械领域的非线性分析场景。本文基于清华讲义,系统梳理ANSYS入门方法,涵盖单元、材料、几何、网格、求解与后处理全流程。 阅读详情

相关推荐

计算机导论期末知识点及试题总结 [近三万字总结 · 全]

计算机网络:计算机网络是利用通信线路连接起来相互独立的计算机的集合,其主要目的是实现数据通信和资源共享。 计算机病毒:破坏计算机功能或数据,影响计算机使用,并能自我复制的一组计算机指令或程序。 操作系统:操作系统是由程序和数据结构组成的大型系统软件,它负责计算机的全部软硬件的资源分配,调度和管理,控制各类程序的正常执行,并为用户使用计算机提供良好的环境。 高速缓冲储存器(Cache):位于cpu和内存之间的储存器,其特点是速度快,目的是是储存器的速度与cpu的速度相匹配。 总线:若干信号线的集合,是

这个人好有趣....hh 1万+

java中事务的属性_Spring事务属性具体解释

应用程序开发复杂性由RodJohnson创建的。框架的主要优势之中的一个就是其分层架构,分层架构同意使用者选择使用哪一个组件,同一时候为 J2EE应用程序开发提供集成的框架。Spring使用主要的JavaBean来完毕曾经仅仅可能由EJB完毕的事情。然而。Spring的用途不仅限于server端的开发。从简单性、可測试性和松耦合的角度而言,不论什么Java应用都能够从Spring中受益。Sprin...

weixin_42458217的博客 326

从零上手:基于英飞凌TC377的UDE STK 5.0实战调试指南

本文详细介绍了基于英飞凌TC377芯片和UDE STK 5.0的实战调试指南,涵盖硬件连接、工作空间配置、程序烧录、多核调试等关键步骤。特别针对汽车电子领域常见的多核架构调试难题,提供了断点设置、变量监控等实用技巧,帮助开发者快速上手并优化调试效率。

weixin_30839881的博客 682

Spring框架 编程式事务 事务的传播行为(一)

spring编程式事务的传播行为,仅为个人理解,如有错误,请大佬指正。万分感谢

moyuxi_的博客 713

电力抄表协议DL/T645和698.45到底有啥区别?一张图帮你选对协议

本文深入对比了电力抄表协议DL/T645和DL/T698.45的技术差异,从协议架构、报文结构、功能覆盖到实施成本进行全面分析。通过实际案例和数据,揭示698.45协议在通信效率、业务扩展性和长期成本上的优势,并提供清晰的选型决策流程图,帮助工程师根据具体需求选择最适合的电力抄表协议。

weixin_38168696的博客 401

EGO_Planner代码学习(三):px4ctrl代码流程

上节阅读了EGO_Planner的轨迹服务器部分的代码,其实质是将规划器生成的轨迹进行离散化,间隔10ms计算当前时刻在轨迹上的位置,并发送到话题上。这两天抽空看了下控制器部分的代码,在l这个软件包里,它的功能是进行px4的模式识别和上层控制,通过线性控制器把发布过来的位置命令解算成飞控的控制量,通过mavros发送给px4。下面就详细看一下它的启动过程。

qq_41069236的博客 6805

Java中的事务及使用详解

Java中的事务及使用 什么是事务? 事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。 为什么要事务

weixin_42374969的博客 2608

Unity3D Lua与C#的相互调用与性能剖析详解

在游戏开发中,经常会遇到Lua与C#之间的相互调用的情况。本文将详细介绍Unity3D中Lua与C#的相互调用的方式,并对其性能进行剖析。对惹,这里有一个游戏开发交流小组,希望大家可以点击进来一起交流一下开发经验呀!一、Lua与C#的相互调用方式Lua调用C#在Unity3D中,可以通过Lua调用C#的方式来实现Lua与C#的相互调用。具体步骤如下:(1)首先需要在Unity3D项目中导入Lua的相关库,例如tolua或者xlua。

weixin_49669470的博客 1211

Spring之事务详解

1.Spring事物的定义: 事务,就是一组操作数据库的动作集合。事务是现代数据库理论中的核心概念之一。 如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事务。 当所有的步骤像一个操作一样被完整地执行,我们称该事务被提交。 由于其中的一部分或多步执行失败,导致没有步骤被提交,则事务必须回滚到最初的系统状态。 2. spring七个事务传播属性: PROP......

上善若泪 1万+

ROS机器人未知环境自主探索功能包explore_lite最全源码详细解析(五)

本系列文章主要针对ROS机器人常使用的未知环境自主探索功能包explore_lite展开全源码的详细解析,并进行概括总结。 本系列文章共包含六篇文章,前五篇文章主要介绍explore_lite功能包中 explore.cpp、costmap_tools.h、frontier_search.cpp、costmap_client.cpp等源码实现文件中全部函数的详细介绍,第六篇文章进行概括总结,包含自主探索功能包explore_lite的简介,实现未知环境自主探索功能的原理及流程总结,效果演示,使用功能包exp

慕羽★的博客 1510

4.6 知识库使用指南:如何让AI Agent拥有专业知识

本文介绍了如何为AI Agent构建和使用知识库。知识库的作用是为Agent提供专业知识,包含文档、数据和规则,可用于专业问答和知识检索。使用方法包括创建知识库(上传文档)、向量化处理、知识检索以及在Agent中的应用。核心要点是理解知识库的价值和使用流程。文章还提出了构建方法、检索优化和应用实践等思考题,建议准备高质量数据、优化检索效果并持续更新知识库。下节将介绍用LangGraph构建复杂AI应用。

yonggeit的博客 3007

Spring事务传播属性

Spring事务传播属性

qishiheyongshi的专栏 1690

(第七章)FAST开发方法

摘要: FAST是一种轻量级、业务驱动的系统分析与开发框架,适用于中小型项目,强调快速交付和组件化开发。其核心包括8个阶段:范围定义、问题分析、需求分析、逻辑设计、决策分析、物理设计、构造测试和安装发布。特点为结构化、用户参与、迭代渐进,适合需求明确且需快速交付的项目。与RUP(重量级)、敏捷(极轻量)相比,FAST更侧重业务分析和模块化开发。软考中可通过口诀“范围问题求逻辑,决策物理构发布”记忆阶段,并掌握五大开发方法(瀑布、原型、FAST、RUP、敏捷)的核心区别及适用场景。

echo的博客 913

Java开发学习---Spring事务属性、事务传播行为

Java开发学习---Spring事务属性、事务传播行为

guanshengg的博客 180

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java开发学习----Spring事务属性、事务传播行为

当转账业务之间出现异常(int i =1/0),转账失败,tbl_account成功回滚,但是tbl_log表未添加数据。logDao.log("转账操作由"+out+"到"+in+",金额:"+money);logDao.log("转账操作由"+out+"到"+in+",金额:"+money);及其子类进行事务回顾,其他的异常类型是不会回滚的,对应IOException不符合上述条件所以不回滚。//这个异常事务就不会回滚。这块需要更正一个地方,并不是所有的异常都会回滚事务,比如下面的代码就不会回滚。...

lt_xiaodou的博客 206

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Java开发学习(二十二)----Spring事务属性、事务传播行为

当转账业务之间出现异常(int i =1/0),转账失败,tbl_account成功回滚,但是tbl_log表未添加数据。及其子类进行事务回顾,其他的异常类型是不会回滚的,对应IOException不符合上述条件所以不回滚。rollbackFor是指定回滚异常,对于异常事务不应该都回滚么,为什么还要指定?这块需要更正一个地方,并不是所有的异常都会回滚事务,比如下面的代码就不会回滚。运行后,就能实现我们想要的结果,不管转账是否成功,都会记录日志。失败原因:日志的记录与转账操作隶属同一个事务,同成功同失败。

273

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

spring 事务隔离级别和传播行为_Java工程师面试1000题146-Spring数据库事务传播属性和隔离级别...

146、简介一下Spring支持的数据库事务传播属性和隔离级别介绍Spring所支持的事务和传播属性之前,我们先了解一下SpringBean的作用域,与此题无关,仅做一下简单记录。在Spring中,可以在元素的scope属性中设置bean的作用域,来决定这个bean是单实例的还是多实例的。默认情况下,Spring只为每个在IOC容器里声明的bean创建唯一的实例,整个IOC容器范围内都可以共享该实...

weixin_39641463的博客 132

事务属性之7种传播行为

事务属性之7种传播行为

weixin_41007138的博客 118

SSM 框架实战教程 事务传播行为 78-81

SSM 框架实战教程 事务传播行为 78-81

道友 169

19.声明式事务的事务隔离级别和事务传播行为

一:事务属性:事务隔离级别①介绍 数据库系统必须具有隔离并发运行各个事务的能力,使它们不会相互影响,避免各种并发问题。一个事 务与其他事务隔离的程度称为隔离级别。SQL标准中规定了多种事务隔离级别,不同隔离级别对应不同 的干扰程度,隔离级别越高,数据一致性就越好,但并发性越弱。允许Transaction01读取Transaction02未提交的修改。要求Transaction01只能读取Transaction02已提交的修改。

m0_56379670的博客 278

java学习笔记——spring 之声明式事务、事务的传播行为(REQUIRED与REQUIRES_NEW)、事务的隔离级别、设置触发事务回滚的异常、事务的超时、只读属性、XML式的声明式事务配置

5、声明式事务 事务概述 ●在JavaEE企业级开发的应用领域,为了保证数据的完整性和一致性,必须引入数据库事务的概念,所以事务管理是企业级应用程序开发中必不可少的技术。 ●事务就是一组由于逻辑上紧密关联而合并成一个整体(工作单元)的多个数据库操作,这些操作要么都执行,要么都不执行。 ●事务的四个关键属性(ACID) ○原子性(atomicity):“原子”的本意是“不可再分”,事务的原子...

qq_25106373的博客 1430

java中事务的属性_spring中事务的属性

1.传播行为定义了关于客户端和被调用方法的事务边界。传播规则就是在说明新的事务是否要被启动或是挂起,或者方法是否要在事务环境中运行。spring定义了7种不同的传播行为。1)PROPAGATION_MANDATORY表明方法必须要在事务中运行。如果事务不存在,抛出异常2)PROPAGATION_NESTED表示如果当前已经存在一个事务,则该方法应当运行在一个嵌套的事务中。被嵌套的事务可以从当前事务...

weixin_30621429的博客 154

JavaWeb ——事务管理

本文介绍了Spring框架的两大核心之一AOP面向切面编程在事务管理中的应用。主要内容包括:1)通过配置日志可查看事务管理过程;2)事务属性设置,如异常回滚(rollbackFor)和传播行为(propagation);3)传播行为的7种类型及其应用场景,如REQUIRED、REQUIRES_NEW等;4)通过日志过滤功能可方便地筛选事务相关日志。文章通过图示和代码示例展示了Spring事务管理的实现方式和配置技巧。

wuxuanok的博客 379

springboot事务管理

事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。开启事务(一组操作开始前,开启事务):start transaction / begin;进行事务管理,方法执行前,开启事务;回滚事务(中间任何一个操作出现异常,回滚事务):rollback;提交事务(这组操作全部成功后,提交事务):commit;是一组操作的集合,它是一个不可分割的工作单位,这些操作。位置:业务(service)层的方法上、类上、接口上。属性用于控制出现何种异常类型,回滚事务。

qq_65317837的博客 592

spring的事务精讲:ACID到隔离级别

本文解析了Java项目中事务管理的核心面试题,涵盖ACID属性、Spring事务实现及常见问题。主要内容包括:1)通过银行转账场景解释事务的ACID特性;2)演示Spring中@Transactional注解的使用方法;3)分析事务传播行为(REQUIRED与REQUIRES_NEW)在用户注册场景的应用;4)结合库存管理系统说明事务隔离级别及并发问题(脏读、不可重复读、幻读)。文章还总结了事务失效的9种常见场景和解决方案,如数据库引擎选择、方法访问权限、自调用问题等,为面试者提供全面的事务管理知识框架。

一个Java开发工程师的自我修养,从认真记录工作中的点点滴滴开始. 879
上一篇: Java中13 种锁的实现方式有哪些?
下一篇: 【Java SE】对象的构造及初始化
Java_ttcd
博客等级 码龄4年 198粉丝 190原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值