一文带你掌握Spring事务核心:TransactionDefinition详解!

TransactionDefinition详解 - 程序员古德

TransactionDefinition是Spring框架中用于定义事务属性的核心接口。在Spring的事务管理中,这个接口扮演着至关重要的角色,它允许开发者定制事务的各种属性,如隔离级别、传播行为、超时时间以及是否只读。

基本介绍

TransactionDefinition 接口的主要方法:

  1. getIsolationLevel(): 返回事务的隔离级别。隔离级别定义了事务如何与其他事务隔离,以避免如脏读、不可重复读和幻读等问题。Spring 支持多种隔离级别,如 ISOLATION_DEFAULTISOLATION_READ_UNCOMMITTEDISOLATION_READ_COMMITTEDISOLATION_REPEATABLE_READISOLATION_SERIALIZABLE
  2. getPropagationBehavior(): 返回事务的传播行为。传播行为决定了当一个事务方法被另一个事务方法调用时,应该如何传播事务。例如,是否应该启动新的事务、使用现有事务还是挂起现有事务等。Spring 支持如 PROPAGATION_REQUIREDPROPAGATION_REQUIRES_NEWPROPAGATION_NESTED 等多种传播行为。
  3. getTimeout(): 返回事务的超时时间(以秒为单位)。如果一个事务运行的时间超过了这个指定的时间,那么它可能会被底层的事务管理系统自动回滚。
  4. isReadOnly(): 返回事务是否为只读。一个只读事务意味着这个事务只读取数据但不修改数据。在某些情况下,数据库可以利用这个信息来优化性能。
  5. getName(): 返回事务的名称。这是一个可选属性,可以为事务提供一个名称,以便于识别和调试。

如下一个简单的 TransactionDefinition 案例:

/**
 * @版权 Copyright by 程序员古德 <br>
 * @创建人 程序员古德 <br>
 * @创建时间 2023/09/19 15:37 <br>
 */

@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW)  
public void someTransactionalMethod() {  
    // ... business logic ...  
}

在上面的例子中,指定了事务的隔离级别为 READ_COMMITTED 和传播行为为 REQUIRES_NEW。总的来说,TransactionDefinition 接口为 Spring 提供了一种统一和灵活的方式来定义和配置事务的各种属性,使开发者能够根据不同的业务需求调整事务的行为。

场景介绍

电商系统订单处理

在电商系统中,当用户下单时,通常需要在数据库中创建订单记录,同时更新库存和用户的付款状态,这个过程必须是事务性的,以确保数据的一致性。这场景具有以下特点:

  1. 多个库表操作(创建订单、更新库存、更新付款状态)。
  2. 需要确保所有操作都成功才提交事务。

在该场景中 TransactionDefinition 的伪配置如下:

  • 传播行为PROPAGATION_REQUIRED,因为在一个事务上下文中执行所有操作是有意义的。
  • 隔离级别ISOLATION_READ_COMMITTED,以避免脏读,同时允许一定程度的并发。
  • 超时时间:根据业务需要设定,比如30秒。

银行转账系统

在银行转账系统中,从一个账户扣款并向另一个账户存款必须是一个原子操作,如果在扣款后因为某种原因存款失败,整个转账操作必须回滚。这场景具有以下特点:

  1. 涉及两个账户的数据库操作
  2. 需要确保转账操作的原子性

在该场景中 TransactionDefinition 的伪配置如下:

  • 传播行为PROPAGATION_REQUIRED,确保转账操作的原子性。
  • 隔离级别ISOLATION_SERIALIZABLE,因为金融系统通常需要最严格的隔离级别。
  • 超时时间:相对较长,比如60秒,因为金融交易可能涉及更多验证和处理时间。

内容管理系统

在内容管理系统中,发布一篇文章可能包括在数据库中创建文章记录、更新作者统计信息、发送通知等操作,这些操作需要在一个事务中执行,以确保数据的一致性。。这场景具有以下特点:

  1. 多个数据库和外部系统操作(如发送通知)
  2. 需要确保所有操作都成功才提交事务

在该场景中 TransactionDefinition 的伪配置如下:

  • 传播行为PROPAGATION_REQUIRED,以便在一个事务上下文中执行所有操作。
  • 隔离级别ISOLATION_READ_COMMITTED,以平衡性能和一致性。
  • 超时时间:相对较短,比如10秒,因为内容管理系统通常对性能要求较高。

代码案例

假设,我们正在开发一个简单的银行转账系统,需要确保转账操作的原子性。在案例中我们将使用Spring框架的事务管理功能,并通过TransactionDefinition来定义事务属性,核心代码如下:

import org.springframework.beans.factory.annotation.Autowired;  
import org.springframework.jdbc.core.JdbcTemplate;  
import org.springframework.transaction.PlatformTransactionManager;  
import org.springframework.transaction.TransactionDefinition;  
import org.springframework.transaction.TransactionStatus;  
import org.springframework.transaction.support.DefaultTransactionDefinition;  

/**
 * @版权 Copyright by 程序员古德 <br>
 * @创建人 程序员古德 <br>
 * @创建时间 2023/09/19 15:37 <br>
 */
public class BankService {  
  
    @Autowired  
    private PlatformTransactionManager transactionManager;  
  
    @Autowired  
    private JdbcTemplate jdbcTemplate;  
  
    public void transfer(String fromAccount, String toAccount, double amount) {  
        // 定义一个事务属性对象  
        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();  
        transactionDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);  
        transactionDefinition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);  
        transactionDefinition.setTimeout(10); // 设置超时时间为10秒  
        transactionDefinition.setReadOnly(false); // 事务不是只读的  
  
        // 获取事务状态对象  
        TransactionStatus transactionStatus = transactionManager.getTransaction(transactionDefinition);  
  
        try {  
            // 从源账户扣钱  
            jdbcTemplate.update("UPDATE account SET balance = balance - ? WHERE account_number = ?", amount, fromAccount);  
            // 向目标账户加钱  
            jdbcTemplate.update("UPDATE account SET balance = balance + ? WHERE account_number = ?", amount, toAccount);  
  
            // 提交事务  
            transactionManager.commit(transactionStatus);  
            System.out.println("转账成功!");  
        } catch (Exception e) {  
            // 回滚事务  
            transactionManager.rollback(transactionStatus);  
            System.out.println("转账失败!");  
            throw e; // 或者选择记录错误日志等其他处理方式  
        }  
    }  
}

在这个案例中,我们定义了一个transfer方法,用于执行转账操作。

在方法内部,我们首先创建了一个DefaultTransactionDefinition对象,并通过setPropagationBehaviorsetIsolationLevelsetTimeoutsetReadOnly方法配置了事务的属性,然后,我们通过transactionManager.getTransaction方法获取了一个TransactionStatus对象,该对象代表了当前事务的状态,在try-catch块中,我们执行了实际的数据库操作(扣钱和加钱),并在成功的情况下提交事务,失败的情况下回滚事务。

最后,我们根据事务的执行结果输出相应的提示信息。

源码解读

这里列出了TransactionDefinition核心方法以及变量,其中一些功能含义、功能重复的就以... 其他XXX ... 进行表示,如下:

package org.springframework.transaction;  
  
import java.io.Serializable;  
/**
 * @版权 Copyright by 程序员古德 <br>
 * @创建人 程序员古德 <br>
 * @创建时间 2023/09/19 15:37 <br>
 */
/**  
 * 事务定义接口,用于定义事务的属性。  
 *  
 * @author Juergen Hoeller  
 * @since 16.03.2003  
 */  
public interface TransactionDefinition extends Serializable {  
  
    /**  
     * 支持当前事务,如果当前没有事务,则新建一个事务。  
     * 这是最常见的选择。  
     */  
    int PROPAGATION_REQUIRED = 0;  
  
    //  
  
    /**  
     * 使用默认的事务隔离级别。  
     * 实际的隔离级别由底层数据库决定。  
     */  
    int ISOLATION_DEFAULT = -1;  
  
    // ... 其他隔离级别常量 ...  
  
    /**  
     * 返回事务的传播行为。  
     * <p>事务的传播行为决定了当在一个事务方法中被另一个事务方法调用时,如何使用事务。  
     * 例如:{@code PROPAGATION_REQUIRED}表示当前方法必须在事务中运行。如果当前存在事务,则加入该事务;  
     * 如果当前没有事务,则新建一个事务。</p>  
     * @return 事务的传播行为常量,如{@code PROPAGATION_REQUIRED}等。  
     */  
    int getPropagationBehavior();  
  
    /**  
     * 返回事务的隔离级别。  
     * <p>事务的隔离级别决定了事务如何处理并发问题。不同的隔离级别会影响脏读、不可重复读和幻读等问题。</p>  
     * @return 事务的隔离级别常量,如{@code ISOLATION_READ_COMMITTED}等。  
     */  
    int getIsolationLevel();  
  
    /**  
     * 返回事务的超时时间(以秒为单位)。  
     * <p>如果事务在规定的时间内没有完成,则会被自动回滚。</p>  
     * @return 超时时间(秒),默认值为-1,表示永不超时。  
     */  
    int getTimeout();  
  
    /**  
     * 返回事务是否为只读。  
     * <p>只读事务不会修改数据,因此可以进行一些优化。</p>  
     * @return 如果事务为只读,则返回{@code true};否则返回{@code false}。  
     */  
    boolean isReadOnly();  
  
    /**  
     * 返回事务的名称。  
     * <p>事务名称可以用于日志记录、监控和调试。</p>  
     * @return 事务的名称,如果没有设置则返回{@code null}。  
     */  
    String getName();  
}

核心总结

TransactionDefinitionSpring框架中用于定义事务属性的核心接口,为开发者提供了事务管理的标准化方式。通过它,我们可以设置事务的传播行为、隔离级别、超时时间和只读属性等,确保数据在并发场景中的一致性和完整性。在实际应用中,TransactionDefinition与其他Spring组件如PlatformTransactionManager结合使用,为数据库操作提供了原子性、一致性、隔离性和持久性的保障,是构建健壮、可维护企业级应用的关键。熟悉并正确使用TransactionDefinition,对于提高系统性能和数据安全性具有重要意义。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/243823.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【抄作业】ImportError :cannot import name xxxxxx ,原博主Activewaste

前情介绍 网上关于这种问题的解决方案一大堆&#xff0c;但是绝大多数都是不适用&#xff0c;或者说解决不了问题&#xff0c;我根据别人所遇到的和我自己遇到的&#xff0c;对这个问题整理了一下&#xff0c;希望能解决这个问题。 问题分析 一、缺少这个module或者func或者p…

代码随想录算法训练营第五十二天 _ 动态规划_300. 最长递增子序列、674.最长连续递增序列、718.最长重复子数组。

学习目标&#xff1a; 动态规划五部曲&#xff1a; ① 确定dp[i]的含义 ② 求递推公式 ③ dp数组如何初始化 ④ 确定遍历顺序 ⑤ 打印递归数组 ---- 调试 引用自代码随想录&#xff01; 60天训练营打卡计划&#xff01; 学习内容&#xff1a; 300. 最长递增子序列 动态规划五…

外汇天眼:投资者最大的敌人——你的大脑

人类大脑的三层构成 为了深入了解投资者做出非理性决策的原因&#xff0c;考虑人脑及其对快乐和痛苦的反应是很有启发性的。 我们的大脑已经进化了数百万年&#xff0c;由三层组成。 核心是我们原始的大脑&#xff0c;它提供了维持我们生存的战斗或逃跑本能。 上面覆盖着一个…

前端如何使用express写一个简单的服务

相信不少前端平常在日常工作中肯遇见过后端API接口没开发出来的时候吧 前端提升小技巧 自己使用nodejs——express ,koa&#xff0c;egg开发接口吧(本人比较喜欢egg和express) 今天先分享一下express 下面是一个简单的demo 1、首先咱们可以新建一个文件夹,创建一个app.js 下…

循环神经网络(1)循环神经网络的记忆能力实验

循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一类具有短期记忆能力的神经网络&#xff0e;在循环神经网络中&#xff0c;神经元不但可以接受其他神经元的信息&#xff0c;也可以接受自身的信息&#xff0c;形成具有环路的网络结构&#xff…

Github、Gitee优秀的开源项目分享

先赞后看&#xff0c;养成习惯&#xff01;&#xff01;&#xff01;❤️ ❤️ ❤️ 资源收集不易&#xff0c;如果喜欢可以关注我哦&#xff01; ​如果本篇内容对你有所启发&#xff0c;欢迎访问我的个人博客了解更多内容&#xff1a;链接地址 ​ Java 项目 javacore - Java …

ArkTS组件通信

父子通信 情况一&#xff1a;子组件只展示父组件中的状态 父组件通过 State修饰符 定义变量&#xff0c;子组件通过 Prop修饰符 获取变量。 Prop是 「单向传递」&#xff0c;父组件将变量「拷贝」一份交给子组件使用&#xff0c;子组件不可修改变量。 父组件 // 声明变量 …

java写个爬虫抓取汽车之家车型配置参数

前几天有个搞工程的表弟找我&#xff0c;问我什么车好&#xff0c;可以经常跑工地的&#xff0c;看上去又有面子。于是我挥动发财的小手&#xff0c;写一个爬虫程序&#xff0c;筛选并整理了一些数据&#xff0c;并附上下载的图片提供参考&#xff0c;看中了果断第二天提车到手…

C#教程(一):面向对象

1、介绍 C#是一种多范式编程语言&#xff0c;但其中一个主要的编程范式是面向对象编程&#xff08;OOP&#xff09;。面向对象编程有一些特点&#xff0c;而C#提供了丰富的功能来支持这些特点。 2、面向对象特点 封装&#xff08;Encapsulation&#xff09;&#xff1a; 封装…

华为OD机试-传递悄悄话(JavaPythonGo)100%通过率

题意 给定一个二叉树,每个节点上站着一个人,节点数字表示父节点到该节点传递悄悄话需要花费的时间。初始时,根节点所在位置的人有一个悄悄话想要传递给其他人,求二又树所有节点上的人都接收到悄悄话花费的时间。 输入 给定一叉树 09 20-1-1 157-1-1-1-132 注:-1表示空节…

Unity | AVpro的最基础使用方法(视频播放插件)

一、 AVpro的使用方法 (一)准备播放器MediaPlayer 1. AVpro的播放器是MediaPlayer&#xff0c;在Heirarchy面板里创建 2.播放器里放视频 a.把视频放到StreamingAssets文件夹下 b.你就可以在MediaPlayer里面找到这个视频 c.选中以后&#xff0c;就会变成 这里点击播放可以播放…

WEX ISO 8583通信协议

1、什么是ISO 8583 ISO 8583是国际标准化组织&#xff08;ISO&#xff09;定义的一种金融交易协议&#xff0c; 它定义了一种消息格式&#xff0c;用于在不同的金融系统之间传递交易请求和响应2、Java如何实现ISO 8583 1、引入依赖包<dependency><groupId>org.jp…

spring boot 实现直播聊天室(二)

spring boot 实现直播聊天室(二) 技术方案: spring bootnettyrabbitmq 目录结构 引入依赖 <dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.96.Final</version> </dependency>Si…

使用YOLOv8训练图集详细教程

准备自己的数据集 训练YOLOv8时&#xff0c;选择的数据格式是VOC&#xff0c;因此下面将介绍如何将自己的数据集转换成可以直接让YOLOv8进行使用。 1、创建数据集 我的数据集都在保存在mydata文件夹&#xff08;名字可以自定义&#xff09;&#xff0c;目录结构如下&#xf…

万界星空科技MES---制造企业的加工生产模式

在现代制造业中&#xff0c;加工生产模式是制造企业组织和管理生产过程的重要方面。不同的加工模式适用于不同的生产需求和产品类型。其中流水型、离散型和混合型是三种常见的加工生产模式。1. 流水型加工模式 流水型加工模式是一种高度自动化的生产方式&#xff0c;适用于…

羊大师解答,鲜羊奶应该怎样煮才好喝?

羊大师解答&#xff0c;鲜羊奶应该怎样煮才好喝&#xff1f; 你是否对如何煮鲜羊奶感到困惑&#xff1f;继续阅读本文&#xff0c;小编羊大师将为大家揭秘鲜羊奶的烹饪方法。不管是作为配料还是单独享用&#xff0c;了解如何煮鲜羊奶将会让您获得更加美味又营养丰富的食物。接…

mysql8 windows下修改my.ini配置 this is incompatible with sql_mode=only_full_group_by

1、找到安装路径 show variables like %sql_mode;SHOW VARIABLES LIKE config_file;SHOW VARIABLES LIKE %datadir%;SHOW VARIABLES; 2、修改 sql_modeSTRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

第二证券:防御性板块逆势活跃 A股结构性机会轮动

昨日商场慎重张望心境升温&#xff0c;个股跌多涨少。防御性板块中的医药、燃气板块涨幅居前。医药板块中&#xff0c;拓新药业、森萱医药涨超19%&#xff0c;百利天恒、亨迪药业、新赣江等多股涨超10%。 据中国气候网消息&#xff0c;从12月12日夜间初步&#xff0c;新一轮寒…

注塑模具ERP有哪些功能?可以帮助企业解决什么难题

不同的注塑模具有不同的业务流程和生产环节&#xff0c;有些生产企业在订单、物料需求计划、车间、班组负荷评估、项目成本核算、边角料统计分析等方面还存在不少问题。 与此同时&#xff0c;也有部分注塑模具企业通过ERP软件科学制定注塑生产排产&#xff0c;智能核算注塑物料…

算法通关村第十八关-黄金挑战回溯困难问题

大家好我是苏麟 , 今天带来几道回溯比较困难的题 . 回溯有很多比较难的问题&#xff0c;这里我们看两个&#xff0c;整体来说这两个只是处理略复杂&#xff0c;还不是最难的问题 . 大纲 IP问题 IP问题 描述 : 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 …