spring使用xml文件整合事务+druid+mybatis

1.事务

事务(Transaction)是数据库管理系统中的一个重要概念,它表示一组不可分割的操作序列,这些操作要么全部执行成功,要么全部不执行,以确保数据库从一个一致性状态转换到另一个一致性状态。事务具有以下四个基本特性,通常被称为ACID特性.

2. ACID特性

原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间某个点。


一致性(Consistency):事务必须使数据库从一个一致性状态转换到另一个一致性状态。也就是说,事务执行的结果必须符合所有预定义的规则和约束,例如数据的完整性和业务规则
比如:(转账:我有100 张三也有100,我和张三两个人的钱总数是200,这时张三转账给我50,张三只剩50,而我收款了有了150,那么我们两个人加起来的钱还是200,不管谁转给谁总数是不变的)


隔离性(Isolation):并发执行的事务之间不会互相影响。事务的隔离性描述了多个事务并发执行时,事务之间的相互影响程度。不同的数据库系统可能提供不同级别的隔离性,例如读未提交(Read
Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable
Read)和串行化(Serializable)。


持久性(Durability):一旦事务被提交,它对数据库所做的更改就是永久性的。即使系统发生故障,事务的结果也不会丢失。

3. 事务注解@Transactional

事务注解标注的地方:
                 1.类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息,会导致事务控制的粒度太大,注解参数无法根据每个类方法的实际需求设置;因此,一般@Transactional注解都会直接添加的需要的方法上;
                 2. 方法: 当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息;
                 3. 接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效;

4. @Transactional注解两个属性

rollbackFor属性:rollbackFor属性指定遇到什么类型的异常就进行回滚,默认是RuntimeException


propagation属性:propagation属性用于设置事务的椽笔级别,默认的级别就是REQUIRED

5. 事务的传播级别

在Spring框架中,事务管理是通过声明式事务管理来实现的,它允许我们以声明的方式配置事务。Spring事务的传播级别(Propagation
Levels)定义了事务的边界和范围,即当一个事务方法被另一个事务方法调用时,事务如何被传播。Spring定义了7种事务传播级别,它们分别如下:


  1. REQUIRED:表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚)

  2. SUPPORTS:表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行,没有事务则已非事务执行,就是纯方法

  3. MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,就抛出异常。表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常

  4. REQUIRES_NEW:新建事务,如果当前存在事务,就把当前事务挂起。这是用于需要创建独立事务的方法。表示当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。

  5. NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,就把当前事务挂起。

  6. NEVER:以非事务方式执行,如果当前存在事务,就抛出异常。

  7. NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,行为与REQUIRED相同。表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同PROPAGATION_REQUIRED的一样

6. 事务流程图

Spring AOP将通用的功能横向抽取出来作为切面,避免非业务代码侵入到业务代码中;通过@Transactional注解就能让Spring为我们管理事务,免去了重复的事务管理逻辑,减少对业务代码的侵入,让开发人员能够专注于业务层面开发;【这里我们知道事务时基于spring中的AOP(切面)进行实现的】

在这里插入图片描述

7. 必要依赖

 <dependency>
 			<!--mysql连接依赖-->
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <version>8.3.0</version>
        </dependency>

        <!-- druid连接池依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.23</version>
        </dependency>
		
		<!--spring框架依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.1.12</version>
        </dependency>

		<!--spring框架操作使用jdb操作数据库依赖(包括了事务(spring-tx)依赖)-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>6.1.12</version>
        </dependency>
        
        <!--mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.16</version>
        </dependency>
        
        <!-- spring整合mybatis插件依赖 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>3.0.4</version>
        </dependency>

		<!--lombox依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.32</version>
        </dependency>

8. 整合(druid数据源,mybatis,事务)

<?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:mybatis="http://mybatis.org/schema/mybatis-spring"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 扫描包 -->
    <context:component-scan base-package="edu.nf.ch03"/>

    <!-- 整合Druid数据源连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <!-- 注入相关的连接属性 -->
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/demo?useSSL=false&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;timeZone=Asia/Shanghai"/>
        <property name="username" value="root"/>
        <property name="password" value="1234"/>
        <!-- 连接池的属性配置-->
        <!-- 最大连接池数量-->
        <property name="maxActive" value="200"/>
        <!-- 初始化连接池的时候建立的连接个数-->
        <property name="initialSize" value="10"/>
        <!-- 连接池最小连接数-->
        <property name="minIdle" value="10"/>
        <!-- 获取连接的最大等待时间,单位:毫秒-->
        <property name="maxWait" value="2000"/>
        <!-- 检测连接是否有效-->
        <property name="testWhileIdle" value="true"/>
        <property name="testOnReturn" value="false"/>
        <!-- 用一条伪sql来检查连接-->
        <property name="validationQuery" value="select 1"/>
        <!-- 是否缓存PreparedStatement,mysql中建议关闭-->
        <property name="poolPreparedStatements" value="false"/>
    </bean>

    <!-- 整合mybatis, 目的就是将SqlSessionFactory纳入IOC容器,
    SqlSessionFactoryBean实现了Spring的FactoryBean接口,这样spring
    容器就可以通过接口的getObject方法得到SqlSessionFactory并纳入容器中
    -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据源连接池 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 实体类的别名-->
        <property name="typeAliasesPackage" value="edu.nf.ch03.entity"/>
        <!-- 指定mapper映射配置文件的路径-->
        <property name="mapperLocations" value="classpath:mappers/*.xml"/>
    </bean>
    <!-- 指定扫描的dao接口,这样就会基于动态代理在运行时创建Dao接口的代理实现,
     这个代理实现也会自动纳入Spring容器-->
    <mybatis:scan base-package="edu.nf.ch03.dao"/>

    <!-- 装配JDBC本地事务管理器 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据源 -->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!-- 启用事务注解处理器,transaction-manager引用JDBC事务管理器的id -->
    <tx:annotation-driven transaction-manager="txManager"/>
</beans>

9. 创建账户实体类(Account)

Account类

/**
 * 账户实体类
 */
@Data
public class Account {
	// 账户id
    private Integer cardId;
    // 账户卡号
    private String cardNum;
    // 账户余额
    private BigDecimal balance;
}

10. 创建转账业务的接口(TransferService),并创建对应的实现类

TransferService接口

public interface TransferService {

    /**
     * 检查账户余额
     * @param fromUser
     * @param money
     */
    void check(Account fromUser, BigDecimal money);

    /**
     * 转账
     * @param money 转账金额
     * @param formUser 转账人
     * @param toUser 接收人
     */
    void transfer(BigDecimal money, Account formUser, Account toUser);
}

TransferServiceImpl实现类

/**
 * @author xiruo
 * 事务注解@Transactional可以声明在类上(类中的所有方法参与事务),
 * 也可以声明在方法上(当前方法参与事务);
 * rollbackFor属性指定遇到什么类型的异常就进行回滚,默认是RuntimeException
 * propagation属性用于设置事务的级别,默认的级别就是REQUIRED
 */
@Service("transferService")
@RequiredArgsConstructor
@Transactional(rollbackFor = RuntimeException.class,
        propagation = Propagation.REQUIRED)
public class TransferServiceImpl implements TransferService {

    private final AccountDao dao;

	// readOnly为true时,该方法为只读事务,引文查询不需要回滚,只要查询即可
	// 方法和类都标注@Transactional注解时,方法会覆盖类的事务
    @Transactional(readOnly = true)
    @Override
    public void check(Account fromUser, BigDecimal money) {
        //1. 获取转账人信息
        fromUser = dao.getOverByAccount(fromUser.getCardNum());
        //2. 检查转账人余额
        if(fromUser.getBalance().compareTo(money) < 0) {
            throw new RuntimeException("对不起,您的余额不足");
        }
    }

    @Override
    public void transfer(BigDecimal money, Account formUser, Account toUser) {
        //1. 获取转账人信息
        formUser = dao.getOverByAccount(formUser.getCardNum());
        //2. 获取接收人信息
        toUser = dao.getOverByAccount(toUser.getCardNum());
        //3. 转账人扣除转账金额
        formUser.setBalance(formUser.getBalance().subtract(money));
        dao.updateAccount(formUser);
        //4. 接收人添加转账金额
        toUser.setBalance(toUser.getBalance().add(money));
        dao.updateAccount(toUser);
        //引发异常
        //System.out.println(10/0);
    }
}

11. 创建AccountDao接口,以及对应的mapper.xml文件(AccountMapeer)

AccountDao接口

public interface AccountDao {

    /**
     * 查询账户余额
     * @param cardNum 卡号
     * @return 账户信息
     */
    Account getOverByAccount(String cardNum);

    /**
     * 更新账户
     * @param account 账户信息
     */
    void updateAccount(Account account);
}

AccountMapeer

<?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="edu.nf.ch03.dao.AccountDao">

    <resultMap id="accountMap" type="edu.nf.ch03.entity.Account">
        <id property="cardId" column="card_id"/>
        <result property="cardNum" column="card_num"/>
        <result property="balance" column="balance"/>
    </resultMap>

    <select id="getOverByAccount" resultMap="accountMap">
        select card_id, card_num, balance from account_info where card_num = #{cardNum}
    </select>

    <update id="updateAccount">
        update account_info set balance = #{balance} where card_num = #{cardNum}
    </update>
</mapper>

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

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

相关文章

大语言模型LLM综述

一、LM主要发展阶段 1.1、统计语言模型SLM 基于统计学习方法&#xff0c;基本思想是基于马尔可夫假设HMM建立词概率预测模型。如n-gram语言模型 1.2、神经语言模型NLM 基于神经网络来做词的分布式表示。如word2vec模型 1.3、 预训练语言模型PLM 预训练一个网络模型来做词表…

【Jenkins实战】Windows安装服务启动失败

写此篇短文&#xff0c;望告诫后人。 如果你之前装过Jenkins&#xff0c;出于换域账号/本地帐号的原因想重新安装&#xff0c;你大概率会遇上一次Jenkins服务启动失败提示&#xff1a; Jenkins failed to start - Verify that you have sufficient privileges to start system…

Linux kernel 堆溢出利用方法(二)

前言 本文我们通过我们的老朋友heap_bof来讲解Linux kernel中off-by-null的利用手法。在通过讲解另一道相对来说比较困难的kernel off-by-null docker escape来深入了解这种漏洞的利用手法。&#xff08;没了解过docker逃逸的朋友也可以看懂&#xff0c;毕竟有了root权限后&a…

微服务(一)

目录 1.认识微服务 1.1.单体架构 1.2.微服务 1.3.SpringCloud SpringCloud版本 SpringBoot版本 2.服务注册和发现 2.1.注册中心原理 2.2.Nacos注册中心 2.3.服务注册 2.3.1.添加依赖 2.3.2.配置Nacos 2.4.服务发现 2.4.1.引入依赖 2.4.2.配置Nacos地址 2.4.3.发…

ubontu--cuDNN安装

1. 下载 cuDNN https://developer.nvidia.com/cudnn 2. 拷贝到服务器/home/<username>文件夹下 解压缩到当前文件夹&#xff1a; tar -xvf cudnn-linux-x86_64-9.5.1.17_cuda11-archive.tar.xz复制头文件和库文件到cuda安装目录/usr/local/cuda/ sudo cp /home/usern…

Vue 批量注册组件实现动态组件技巧

介绍 Vue 动态组件的应用场景很多,可应用于动态页签,动态路由等场景,其核心原理是批量注册。在Vue2和Vue3中实现原理相同,只是语法略有差异。 Vue2 实现 基于 webpack require.context() 是webpack提供的一个自动导入的API 参数1&#xff1a;加载的文件目录 参数2&#xff…

WEB攻防-通用漏洞SQL读写注入MYSQLMSSQLPostgraSQL

知识点&#xff1a; 1、SQL注入-MYSQL数据库&#xff1b; 2、SQL注入-MSSQL数据库&#xff1b; 3、SQL注入-PostgreSQL数据库&#xff1b; 首先要找到注入点 详细点&#xff1a; Access无高权限注入点-只能猜解&#xff0c;还是暴力猜解 MYSQL&#xff0c;PostgreSQL&am…

NocoBase 本周更新汇总:提升工作流易用性

汇总一周产品更新日志&#xff0c;最新发布可以前往我们的博客查看。 NocoBase 目前更新包括两个分支&#xff1a;main 和 next 。 main &#xff1a;截止目前最稳定的版本&#xff0c;推荐安装此版本。 next&#xff1a;内测版&#xff0c;包含一些未发布的新特性&#xff…

python高级之面向对象编程

一、面向过程与面向对象 面向过程和面向对象都是一种编程方式&#xff0c;只不过再设计上有区别。 1、面向过程pop&#xff1a; 举例&#xff1a;孩子上学 1. 妈妈起床 2. 妈妈洗漱 3. 妈妈做饭 4. 妈妈把孩子叫起来 5. 孩子起床 6. 孩子洗漱 7. 孩子吃饭 8. 妈妈给孩子送学校…

❤React-React 组件基础(类组件)

❤React-React 组件基础 1、组件化开发介绍 组件化开发思想&#xff1a;分而治之 React的组件按照不同的方式可以分成类组件&#xff1a; 划分方式一&#xff08;按照组件的定义方式&#xff09; 函数组件(Functional Component )和类组件(Class Component)&#xff1b; …

在Java中使用ModelMapper简化Shapefile属性转JavaBean实战

目录 前言 一、原始的处理办法 1、使用Set方法来转换 2、使用构造方法转换 二、基于ModelMapper的动态转换 1、ModelMapper简介 2、集成到项目中 3、Shapefile属性读取 三、总结 前言 在现代软件开发中&#xff0c;尤其是在多层架构中&#xff0c;经常需要将数据从一个…

Arduino IDE Windows 系统 离线安装 esp32 开发板 亲测好用。

1、前提条件需要具备特殊网络。 2、官方文档地址&#xff1a;Installing - - — Arduino ESP32 latest documentation 3、系统&#xff1a;Windows10 Arduino IDE 版本2.3.3 之前安装的esp32开发板的版本是2.0.13&#xff0c;由于之前没有接触过esp32开发&#xff0c;也没…

期权懂|请问如何用期权进行风险管理?

期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 请问如何用期权进行风险管理&#xff1f; 一、期权可以选择交易活跃的期权合约进行风险管理&#xff1a; 对于初级投资者来说&#xff0c;选择交易活跃的期权合约是非常重要的。…

GNU构建系统和Autotool

1、前言 经常使用Linux的开发人员或者运维人员&#xff0c;可能对configure->make->make install相当熟悉。事实上&#xff0c;这叫GNU构建系统&#xff0c;利用脚本和make程序在特定平台上构建软件。这种方式成为一种习惯&#xff0c;被广泛使用。本文从用户视角和开发…

NLP论文速读|ScPO:自我一致性的偏好优化(Self-Consistency Preference Optimization)

论文速读|Self-Consistency Preference Optimization 论文信息&#xff1a; 简介&#xff1a; 这篇论文试图解决的问题是如何在没有人类标注数据的情况下&#xff0c;提高大型语言模型&#xff08;LLMs&#xff09;在复杂推理任务上的性能。现有的自我对齐技术往往因为难以分配…

【前端学习指南】Vue computed 计算属性 watch 监听器

&#x1f36d; Hello&#xff0c;我是爱吃糖的范同学 &#x1f534; 想把自己学习技术的经历和一些总结分享给大家&#xff01; &#x1f534; 通过这样的方式记录自己成长&#xff0c;同时沉淀自己的技术&#xff0c;我会把所有额外的时间和经历投放到CSDN和公众号&#xff0…

自动驾驶合集(更新中)

文章目录 车辆模型控制路径规划 车辆模型 车辆模型基础合集 控制 控制合集 路径规划 规划合集

vcenter service基本异常处理

服务&#xff1a;vcenter service 版本&#xff1a; 7.0.3 问题描述&#xff1a;无法访问vcenter ui 排障思路&#xff1a; 1. 登入vcenter所在服务器执行基础排查&#xff1a;内存、cpu、磁盘、网络等&#xff0c;发现磁盘日志目录已经爆满&#xff0c;删除180天前的日志恢…

Background Tasks Kit(后台任务开发服务)

11_13日学习笔记 Background Tasks Kit&#xff08;后台任务开发服务&#xff09; Background Tasks Kit简介 设备返回主界面、锁屏、应用切换等操作会使应用退至后台。 应用退至后台后&#xff0c;如果继续活动&#xff0c;可能会造成设备耗电快、用户界面卡顿等现象。 为了…

modbus协议 Mthings模拟器使用

进制转换 HEX 16进制 (0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F表示0-15) dec 10进制 n(16进制) -> 10 abcd.efg(n) d*n^0 c*n^1 b*n^2 a*n^3 e*n^-1 f*n^-2 g*n^-3&#xff08;10&#xff09; 10 -> n(16进制) Modbus基础概念 高位为NUM_H&…