05、Spring事务详解

news2025/7/21 10:50:54

本文主要介绍Spring中的事务相关知识:
1、熟悉事务管理的三个核心接口
2、了解Spring事务的两种方式
3、掌握基于XML和注解的事务使用

1、Spring事务管理概述

1、事务管理的核心接口

1、PlatformTransactionManager

PlatformTransactionManage接口是Spring平台提供的平台事务管理器,主要用于管理事务。该接口中主要包含3个事务操作方法。

  • TransactionStatus getTransaction(TransactionDefinition definition):根据事务定义信息从事务环境中返回一个已存在的事务,或者创建一个新的事务。
  • void commit(TransactionStatus status):根据事务的状态提交事务,如果事务状态已经标识为 rollback-only,该方法执行回滚事务的操作。
  • void rollback(TransactionStatus status):将事务回滚,当 commit 方法抛出异常时,rollback 会被隐式调用。

2、使用事务选用实现类

  • JDBC 和 MyBatis 使用 DataSourceTransactionManager。
  • Hibernate 使用 HibernateTransactionManager。
  • JPA 使用 JpaTransactionManager。

3、TransactionDefinition接口

  • int getPropagationBehavior():获取事务的传播行为。
  • int getIsolationLevel();:获取事务的隔离级别。
  • int getTimeout();:获取事务的超时时间。
  • boolean isReadOnly();:判断事务是否只读。
  • String getName();:获取事务对象名称。

4、TransactionStatus

  • boolean isNewTransaction(); 判断是否是新的事务
  • boolean hasSavepoint(); 判断是否存在保存点
  • void setRollbackOnly(); 设置事务回滚
  • boolean isRollbackOnly(); 判断是否回滚
  • void flush(); 刷新事务
  • boolean isCompleted(); 判断事务是否完成

2、事务管理的方式

  • 编程式事务:通过编写代码来管理事务;
  • 声明式事务:通过XML配置或注解来管理事务。

2、基于XML方式的声明式事务

1、创建一个maven项目导入相关依赖

    <dependencies>
        <!-- 数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.45</version>
            <scope>runtime</scope>
        </dependency>
        <!-- 数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.9</version>
        </dependency>
        <!-- MyBatis 相关 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!-- Spring 集成 MyBatis 的依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>

        <!--控制台日志-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <!-- Spring 相关 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.13</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.8.RELEASE</version>
        </dependency>
        <!-- 测试相关 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.8.RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

2、准备数据库

CREATE TABLE `account`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `balance` decimal(10, 0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `account` VALUES (1, 10000);
INSERT INTO `account` VALUES (2, 0);

3、编写dao接口及Mapper.xml文件

  • dao接口
package cn.simplelife.mapper;

import org.apache.ibatis.annotations.Param;

import java.math.BigDecimal;

/**
 * @ClassName AccountMapper
 * @Description
 * @Author simplelife
 * @Date 2022/11/23 15:34
 * @Version 1.0
 */

public interface AccountMapper {
    void addBalance(@Param("inId") Long inId, @Param("amount") BigDecimal amount);

    void subtractBalance(@Param("outId") Long outId, @Param("amount") BigDecimal amount);
}
  • mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.simplelife.mapper.AccountMapper">

    <update id="addBalance">
        UPDATE account
        SET balance=balance + #{amount}
        WHERE id = #{inId}
    </update>

    <update id="subtractBalance">
        UPDATE account
        SET balance=balance - #{amount}
        WHERE id = #{outId}
    </update>
</mapper>

4、编写实体类

package cn.simplelife.domain;

import lombok.Data;

import java.math.BigDecimal;

/**
 * @ClassName Account
 * @Description
 * @Author simplelife
 * @Date 2022/11/23 15:15
 * @Version 1.0
 */
@Data
public class Account {
    private Long id;
    private BigDecimal balance;
}

5、编写mybatis-config.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!--配置别名-->
    <typeAliases>
        <package name="cn.simplelife.domain"/>
    </typeAliases>

    <!--关联mapper-->
    <mappers>
        <mapper resource="cn/simplelife/mapper/*.xml"/>
    </mappers>
</configuration>

6、编写业务接口及实现类

  • 业务层接口
package cn.simplelife.service;

import java.math.BigDecimal;

/**
 * @ClassName IAccountService
 * @Description
 * @Author simplelife
 * @Date 2022/11/23 17:09
 * @Version 1.0
 */

public interface IAccountService {
    void transfer(Long outId, Long inId, BigDecimal amount);
}
  • 业务层实现类
package cn.simplelife.service.impl;

import cn.simplelife.mapper.AccountMapper;
import cn.simplelife.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * @ClassName IAccountServiceImpl
 * @Description
 * @Author simplelife
 * @Date 2022/11/23 17:10
 * @Version 1.0
 */

@Service
public class IAccountServiceImpl implements IAccountService {

    @Autowired
    private AccountMapper accountMapper;

    @Override
    public void transfer(Long outId, Long inId, BigDecimal amount) {
        accountMapper.subtractBalance(outId, amount);
        System.out.println(10 / 0);
        accountMapper.addBalance(inId, amount);
    }
}

7、编写applicationContext.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--配置Ioc 和 Di注解解析器-->
    <context:component-scan base-package="cn.simplelife.*"/>

    <!--  关联db.properties-->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--配置数据源-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${password}"/>
    </bean>

    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="druidDataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.simplelife.mapper"/>
    </bean>
    <!--配置事务管理器-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"/>
    </bean>

    <!--配置增强 WHEN WHAT-->
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <!--配置切入点 WHERE-->
        <aop:pointcut id="txPoint" expression="execution(* cn.simplelife.service.impl.*ServiceImpl.*(..))"/>
        <!--关联三者-->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    </aop:config>

    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
</beans>

8、编写测试类

import cn.simplelife.service.IAccountService;
import cn.simplelife.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.math.BigDecimal;

/**
 * @ClassName SqlSessionFactoryTest
 * @Description
 * @Author simplelife
 * @Date 2022/11/23 15:26
 * @Version 1.0
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SqlSessionFactoryTest {
    @Autowired
    private IAccountService iAccountService;

    @Test
    public void getSqlSessionTest() {
        System.out.println(MybatisUtils.getSqlSession());
        iAccountService.transfer(1L, 2L, new BigDecimal("100"));
    }
}

9、测试结果

  • 成功
    在这里插入图片描述
    在这里插入图片描述
  • 失败

在这里插入图片描述
在这里插入图片描述

3、基于注解的事务

1、修改配置文件如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--配置IocDi注解解析器-->
    <context:component-scan base-package="cn.simplelife.*"/>

    <!--  关联db.properties-->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--配置数据源-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${password}"/>
    </bean>

    <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="druidDataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="cn.simplelife.mapper"/>
    </bean>
    
    <!--配置事务管理器-->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="druidDataSource"/>
    </bean>
    <!--开启事务注解支持-->
    <tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>
</beans>

2、修改业务层方法

添加注解

package cn.simplelife.service.impl;

import cn.simplelife.mapper.AccountMapper;
import cn.simplelife.service.IAccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * @ClassName IAccountServiceImpl
 * @Description
 * @Author simplelife
 * @Date 2022/11/23 17:10
 * @Version 1.0
 */

@Service
public class IAccountServiceImpl implements IAccountService {

    @Autowired
    private AccountMapper accountMapper;

    @Override
    @Transactional
    public void transfer(Long outId, Long inId, BigDecimal amount) {
        accountMapper.subtractBalance(outId, amount);
        System.out.println(10 / 0);
        accountMapper.addBalance(inId, amount);
    }
}

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

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

相关文章

FineReport智能表格软件-JS实现大数据集导出(一)

前言 帆软FineReport大批量数据导出的时候&#xff0c;会对服务器、网络传输、数据库造成一定的压力。为了防止这样的风险&#xff0c;FineReport 11.0 新增了「大数据集导出」的功能&#xff0c;可直接根据数据集结果进行导出。 1.接口简介与注意事项 1.1 接口简介 大数据…

Redis订阅发布

Redis发布订阅(pub/sub)是一种消息通信模式&#xff1a;发送者(pub)发送消息&#xff0c;订阅者(sub)接受消息。&#xff08;微信、微博、关注系统&#xff09; Redis客户端可以订阅任意数量的频道 订阅发布消息图&#xff1a; 三个角色&#xff1a;消息发送者、频道、消息订…

VMware 安装Ubuntu22.04

0、前提条件 操作系统&#xff1a;Windows10 VMware Workstation版本&#xff1a;15.1.0 build-13591040 1、安装 下载地址&#xff1a;下载Ubuntu桌面系统 | Ubuntu 打开VMware&#xff0c;选择文件 -> 新建虚拟机 配置类型选择典型&#xff0c;单击“下一步”按钮 选择…

python操作Excel之提取字符串中的中文/过滤字符串(win32com)

Python实用篇-Excel1.前言2.关于Excel3.win32com库操作4.问题解决4.1.问题描述4.2.安装库4.3.编码与解决1.前言 本人大学期间自学了Python后&#xff0c;但是又因不是大数据相关专业&#xff0c;并且没有计划从事Python相关方向&#xff0c;之后就几乎没有怎么使用过Python了。…

智慧城市应用数据治理的作用有哪些?

智慧城市是基础设施发展的新热词。 主要是指在城市规划、设计、建设、管理与运营等领域中&#xff0c;通过物联网、云计算、大数据、空间地理信息集成等智能计算技术的应用&#xff0c;使得城市管理、教育、医疗、房地产、交通运输、公用事业和公众安全等城市组成的关键基础设施…

现代密码学导论-10-EAV安全

目录 3.2.1 安全的基本定义&#xff08;EAV-安全&#xff09; 不可区分实验 The adversarial indistinguishability experiment DEFINITION 3.8 EAV-安全的等价定义&#xff08;一&#xff09; DEFINITION 3.9 EAV-安全的等价定义&#xff08;二&#xff09; 证明EAV-安全…

[b01lers2020]Welcome to Earth

刚点进来会一直加载&#xff0c;然后跳转到了/die 看一下刚进来页面的源代码 <!DOCTYPE html> <html><head><title>Welcome to Earth</title></head><body><h1>AMBUSH!</h1><p>Youve gotta escape!</p>&l…

leetcode:1157. 子数组中占绝大多数的元素【暴力遍历 + 随机算法相信概率】

目录题目截图题目分析暴力二分随机二分总结题目截图 题目分析 一个很暴力的思路就是把每个num出现的idx记录起来&#xff0c;然后按出现的频率排序优化每次query&#xff0c;遍历每个元素和频率&#xff0c;频率如果已经比threhold小就没有看的必要&#xff0c;直接break如果比…

虎扑论坛数据分析

论坛为用户提供了相同的业余爱好&#xff0c;互动和交流的广阔平台&#xff0c;以及由此产生的庞大数据和复杂的用户交互场景也包含有价值的信息&#xff0c;本文关于虎扑论坛的帖子&#xff0c;个人信息分析&#xff0c;探讨虎扑论坛的用户是什么是什么特点&#xff1f;最近我…

Spring Cloud Stream绑定器架构解析与开发

Spring Cloud Stream绑定器架构解析与开发 根据不同的使用场景我们通常会选择相适应的消息中间件&#xff0c;例如对于日志收集场景可能会选择使用Kafka&#xff0c;对于订单场景通常会选择RocketMQ&#xff0c;不同消息中间件的客户端是不同的&#xff0c;我们需要针对不同消息…

智慧城市面临的机遇与挑战

区域中心城市建设需要智慧城市支撑 建设区域中心城市&#xff0c;除了需要具备在公路、铁路、航空等区域中心城市的枢纽硬件设施外&#xff0c;更需要充分发挥信息化强有力的凝聚和辐射作用&#xff0c;提升区域中心城市在区域交通枢纽服务、区域金融商贸服务、区域物流集散服务…

百趣代谢组学文献分享:茶褐素可促进胆固醇降解

​ 为了解决大家每逢过节必长胖的历史性问题&#xff0c;小编今天给大家介绍一篇发表于Nature Communications 的针对于普洱茶促进减肥的研究。 百趣代谢组学文献分享&#xff0c;所谓药食同源&#xff0c;普洱茶是我国西南云南地区特有的一种传统名茶&#xff0c;因其具有治…

[激光原理与应用-18]:《激光原理与技术》-4- 粒子数反转与“光”强放大的基本原理

目录 一、热平衡&#xff1a; 受激辐射 < 受激接收 二、 “光”相干放大 三、粒子数反转&#xff08;population inversion&#xff09; 四、实现粒子数反转的装置&#xff1a;泵浦 五、实现粒子数反转的条件 六、实现粒子数反转的工作物质 七、实现粒子数反转的方式…

【菜菜的sklearn课堂笔记】逻辑回归与评分卡-用逻辑回归制作评分卡-重复值和缺失值处理

视频作者&#xff1a;菜菜TsaiTsai 链接&#xff1a;【技术干货】菜菜的机器学习sklearn【全85集】Python进阶_哔哩哔哩_bilibili 在银行借贷场景中&#xff0c;评分卡是一种以分数形式来衡量一个客户的信用风险大小的手段&#xff0c;它衡量向别人借钱的人&#xff08;受信人&…

「Vue系列」欢迎传送到“Teleport”星球

前言 大家好&#xff0c;我是落叶小小少年&#xff0c;我一直谨记学习不断&#xff0c;分享不停&#xff0c;输入的最好方式是输出&#xff0c;我始终相信 用最核心代码更容易理解深的技术点用通俗易懂的话&#xff0c;讲难的知识点 之前有学习并写了KeepAlive组件的实现原理…

Nginx 报错问题汇总(持续更新ing)

目录 一、nginx: [emerg] invalid number of arguments in "include" directive in C:\Program Files\nginx-1.15.4/conf/nginx.conf:61 总结&#xff1a; 二、nginx: [error] OpenEvent("Global\ngx_reload_2152") failed (5: Access is denied) 解决方…

《Java》图书管理系统(已升级)

目录 前言 效果展示 功能模块 书架 定义书的类 创建书架 用户 User用户类 AdminUser管理员 NormalUser普通用户 功能 接口 FindOperation 查找图书 AddOperation添加图书 DelOperation删除图书 BorrowOperation借阅图书 DisOperation 打印图书 RetOperation归还图…

Spring Boot 3.0.0 GA版本正式发布,期待已久的SpringBoot3发布了

期待已久的SpringBoot3.0.0发布了发布说明新版本的亮点分析1. Java 17 baseline 和 Java 19 支持2. 支持 [GraalVM native images](https://docs.spring.io/spring-boot/docs/3.0.0/reference/html/native-image.html#native-image)&#xff0c;取代实验性的 Spring Native 项目…

linux篇【11】:linux下的线程<中序>

目录 一.线程互斥 1.三个概念 2.互斥 &#xff08;1&#xff09;在执行语句的任何地方&#xff0c;线程可能被切换走 &#xff08;3&#xff09;抢票场景中的问题 &#xff08;4&#xff09;解决方案 3.加锁 &#xff08;1&#xff09;加锁介绍 &#xff08;2&#xf…

STC 51单片机39——汇编语言 按钮流水灯

每按一下按钮&#xff0c;灯就移动一个 ORG 0000H LJMP MAIN ORG 0003H ;中断矢量 LJMP INT MAIN:SETB EA ;开总中断允许“开关” SETB EX0 ;开分中断允许“开关” SETB PX0 ;高优先级 SETB IT0 ;边沿触发 MOV A,#0FEH ;给…