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

news2024/9/29 9:23:30

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,对于提高系统性能和数据安全性具有重要意义。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python创建代理IP池详细教程

一、问题背景 在进行网络爬虫或数据采集时&#xff0c;经常会遇到目标网站对频繁访问的IP进行封禁的情况&#xff0c;为了规避这种封禁&#xff0c;我们需要使用代理IP来隐藏真实IP地址&#xff0c;从而实现对目标网站的持续访问。 二、代理IP池的基本概念 代理IP池是一个包…

《使用ThinkPHP6开发项目》 - 登录接口三【表单验证】

《使用ThinkPHP6开发项目》 - 登录接口一-CSDN博客 https://blog.csdn.net/centaury32/article/details/134974860 在设置用户登录时&#xff0c;由于安全问题会对登录密码进行加密 表单验证这里也可以使用ThinkPHP6自带的验证规则&#xff0c;创建一个验证管理员的文件 ph…

〖大前端 - 基础入门三大核心之JS篇(52)〗- 指定函数上下文 - call和apply

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

大数据存储技术(1)—— Hadoop简介及安装配置

目录 一、Hadoop简介 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;Hadoop发展历史 &#xff08;三&#xff09;Hadoop三大发行版本 &#xff08;四&#xff09;Hadoop的优势 二、Hadoop的组成 &#xff08;一&#xff09;Hadoop1.x和Hadoop2.x的区别​…

RocketMQ源码 Broker-ConsumerFilterManager 消费者数据过滤管理组件源码分析

前言 ConsumerFilterManager 继承了ConfigManager配置管理组件&#xff0c;拥有将内存数据持久化到磁盘文件consumerFilter.json的能力。它主要负责&#xff0c;对在消费者拉取消息时&#xff0c;进行消息数据过滤&#xff0c;且只针对使用表达式过滤的消费者有效。 源码版本&…

SFP3006-ASEMI大电流快恢复二极管SFP3006

编辑&#xff1a;ll SFP3006-ASEMI大电流快恢复二极管SFP3006 型号&#xff1a;SFP3006 品牌&#xff1a;ASEMI 封装&#xff1a;TO-247 最大平均正向电流&#xff1a;30A 最大重复峰值反向电压&#xff1a;600V 产品引线数量&#xff1a;3 产品内部芯片个数&#xff1…

多项式回归

多项式回归 多项式回归 是非线性回归的一种&#xff0c;之前讨论的线性回归都是直线&#xff0c;而多项式回归则是曲线的回归&#xff0c;它通过引入原始预测变量的高阶项&#xff08;如平方、立方等&#xff09;来拟合数据的非线性模式。在多项式回归中&#xff0c;虽然模型对…

06 python 文件基础操作

6.1 .1文件读取操作 演示对文件的读取 # 打开文件 import timef open(02_word.txt, r, encoding"UTF-8") print(type(f))# #读取文件 - read() # print(f读取10个字节的结果{f.read(10)}) # print(f读取全部字节的结果{f.read()})# #读取文件 - readLines() # lines…

头歌-Python 基础

第1关&#xff1a;建模与仿真 1、 建模过程&#xff0c;通常也称为数学优化建模(Mathematical Optimization Modeling)&#xff0c;不同之处在于它可以确定特定场景的特定的、最优化或最佳的结果。这被称为诊断一个结果&#xff0c;因此命名为▁▁▁。 填空1答案&#xff1a;决…

Talk | UCSB博士生王丹青: 大语言模型的协作学习以及个性化生成评估

本期为TechBeat人工智能社区第555期线上Talk。 北京时间12月13日(周三)20:00&#xff0c;加州大学圣塔芭芭拉分校博士生—王丹青的Talk已准时在TechBeat人工智能社区开播&#xff01; 她与大家分享的主题是: “大语言模型的协作学习以及个性化生成评估”&#xff0c;介绍了她的…

re:Invent 产品体验分享:Amazon ElastiCache Serverless 缓存即时扩展功能与感受

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在亚马逊云科技开发者社区、 知乎、自媒体平台、第三方开发者媒体等亚马逊云科技官方渠道&#xff09;。 文章目录 前言产品介绍产品使用步骤1.创建缓存服务2.安全组开放访问权限…

高效营销系统集成:百度营销的API无代码解决方案,提升电商与广告效率

百度营销API连接&#xff1a;构建无代码开发的高效集成体系 在数字营销的高速发展时代&#xff0c;企业追求的是快速响应市场的能力以及提高用户运营的效率。百度营销API连接正是为此而生&#xff0c;它通过无代码开发的方式&#xff0c;实现了电商平台、营销系统和CRM的一站式…

uniapp用picker实现自定义三级联动(children)

数据大概得结构&#xff1a; html: <view class"invite"><u-cell title"点击选则" isLink :value"value" click"showstrue"></u-cell><u-picker :show"shows" ref"uPicker" :columns"…

微服务最佳实践:构建可扩展且高效的系统

微服务架构彻底改变了现代软件开发&#xff0c;提供了无与伦比的敏捷性、可扩展性和可维护性。然而&#xff0c;有效实施微服务需要深入了解最佳实践&#xff0c;以充分发挥微服务的潜力&#xff0c;同时避免常见的陷阱。在这份综合指南中&#xff0c;我们将深入研究微服务的关…

【Vue】vue增加导航标签

系列文章 【Vue】vue增加导航标签 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/134965353 【Vue】Element开发笔记 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/133947977 【Vue】vue&#xff0c;在Windows IIS平台…

关于pytorch中的dim的理解

今天碰到一个代码看起来很简单&#xff0c;但是细究原理又感觉好像不太通不太对劲&#xff0c;就是多维tensor数据的操作&#xff0c;比如&#xff1a;y.sum(dim2)&#xff0c;乍一看很简单数据相加操作&#xff0c;但是仔细一想&#xff0c;这里在第3维度的数据到底是横向相加…

Python中的继承:概念、用法与示例

目录 一、引言 二、继承的概念 三、继承的用法 1、继承父类的属性和方法 2、添加新的属性和方法 3、覆盖父类的方法 四、示例代码展示 五、继承中的多态性 六、继承中的封装和抽象 七、继承中的多重继承 总结 一、引言 面向对象编程&#xff08;OOP&#xff09;是一…

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

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

node加密集合(前端加密、后台解密)

文章目录 一、crypto 加解密生成私密钥公钥加密&#xff08;也可私钥加密&#xff09;私钥解密&#xff08;也可公钥解密&#xff09; 二、node-rsa加解密生成公私秘钥使用公钥加密&#xff08;也可私钥加密&#xff09;使用私钥解密&#xff08;也可公钥解密&#xff09; 三、…

Shell三剑客:正则表达式(元字符)

一、定义&#xff1a;元字符字符是这样一类字符&#xff0c;它们表达的是不同字面本身的含义 二、分类&#xff1a; 1、基本正则表达式元字符 # ^ 行首定位 [rootlocalhost ~]# grep root /etc/passwd root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/…