【Spring进阶系列丨最终篇】一文详解Spring中的事务控制

news2024/11/15 9:12:01

0、说明

本篇文章是【Spring进阶系列】专栏的最后一篇文章,至此,我们对Spring的学习就告一段落,接下来我会持续更新【Spring+SpringMVC+MyBatis整合】专栏,欢迎免费订阅!

文章目录

    • 0、说明
  • 一、Spring事务控制
    • 1、事务的环境准备
      • 1.1、导入依赖
      • 1.2、添加AOP的约束
      • 1.3、数据库准备
      • 1.4、定义Bean
      • 1.5、主配置文件定义
      • 1.6、测试
    • 2、基于xml的声明式事务
      • 2.1、配置事务管理器
      • 2.2、配置事务的通知
      • 2.3、配置AOP
      • 2.4、配置事务的属性
    • 3、基于注解的声明式事务
      • 3.1、配置事务管理器
      • 3.2、在业务类添加注解
      • 3.3、配置JdbcTemplate模板
      • 3.4、在Dao类添加注解
      • 3.5、配置类中扫描包
      • 3.6、开启spring对注解事务的支持
      • 3.7、在业务层@Transactional注解
      • 3.8、测试

在这里插入图片描述

一、Spring事务控制

在这里插入图片描述

  • 事务需要放在业务层(service)
  • Spring的事务是基于AOP的
  • Spring的事务控制有两种:编程式事务【了解】和声明式事务【重点】
  • 声明式事务分为:基于xml配置和基于注解配置

1、事务的环境准备

1.1、导入依赖

<dependencies>

        <!-- 导入Spring的jar包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>

        <!-- 添加对AOP的支持  -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.4</version>
        </dependency>

        <!-- 事务的jar包    -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>

        <!-- 数据库驱动  -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>
  	
  		<!-- 操作数据库的支持	-->
  		<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>

        <!--  单元测试框架  -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
</dependencies>

1.2、添加AOP的约束

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

1.3、数据库准备

create database bank;

use bank;

create table t_account(
	id int primary key auto_increment,
  	name varchar(30),
  	balance int
);

insert into t_account(name,balance) values('段康家',2000);
insert into t_account(name,balance) values('彭依凝',2000);

1.4、定义Bean

// 定义实体
public class Account {
    
    private Integer id;
    
    private String name;
    
    private Integer balance;
}
// 业务接口
public interface AccountService {

    public void transfer(Integer srcId,Integer destId,Integer money);

}
public class AccountServiceImpl implements AccountService {

    @Override
    public void transfer(Integer srcId, Integer destId, Integer money) {
        // 源账号
        Account srcAccount = accountDao.selectById(srcId);
        Integer srcBalance = srcAccount.getBalance();
        srcAccount.setBalance(srcBalance - money);
        
        accountDao.updateById(srcAccount);
        
        // 目标账号
        Account destAccount = accountDao.selectById(destId);
        Integer destBalance = destAccount.getBalance();
        destAccount.setBalance(destBalance + money);
        
        accountDao.updateById(destAccount);
    }
}
// dao接口
public interface AccountDao {
    
    public Account selectById(Integer id);
    
    public void updateById(Account account);
    
}
// dao实现类
public class AccountDaoImpl implements AccountDao {
    @Override
    public Account selectById(Integer id) {

        String sql = "select id,name,balance from t_account where id = ?";

        List<Account> accounts = getJdbcTemplate().query(sql,new BeanPropertyRowMapper<Account>(Account.class),id);

        return accounts.get(0);
    }

    @Override
    public void updateById(Account account) {

        String sql = "update t_account set balance = ? where id = ?";

        getJdbcTemplate().update(sql,account.getBalance(),account.getId());
    }
}

1.5、主配置文件定义

<beans> 
	<!-- 配置Dao层-->
    <bean id="accountDao" class="cn.bdqn.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref=""/>
    </bean>

    <!-- 配置业务层-->
    <bean id="accountService" class="cn.bdqn.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>

    <!-- 配置数据源  -->
    <bean id="dataSource" 																class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql:///bank"></property>
        <property name="username" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

</beans>

1.6、测试

@Test
public void testTransfer() throws Exception{

        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        AccountService accountService = (AccountService) ac.getBean("accountService");
        accountService.transfer(1,2,100);
}

2、基于xml的声明式事务

2.1、配置事务管理器

<!--  1、配置事务管理器  -->
<bean id="transactionManager" 																																		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
</bean>

2.2、配置事务的通知

 <!-- 2、配置事务的通知  -->
<tx:advice id="txAdvice" transaction-manager="transactionManager"/>

2.3、配置AOP

​ 重点是配置切入点表达式及事务通知和切入点表达式的关系

<!-- 3、开启配置AOP 配置切入点表达式及事务通知和切入点表达式的关系-->
<aop:config>
        <aop:pointcut id="pt" expression="execution(* cn.bdqn.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>

2.4、配置事务的属性

​ 注意:事务的属性在tx:advice标签的内部。

isolation:用于指定事务的隔离级别。默认值是DEFAULT,表示使用数据库的默认隔离级别。

propagation:用于指定事务的传播行为。默认值是REQUIRED,表示一定会有事务,增删改的选择。查询方法可以选择SUPPORTS。

read-only:用于指定事务是否只读。只有查询方法才能设置为true。默认值是false,表示读写。

timeout:用于指定事务的超时时间,默认值是-1,表示永不超时。如果指定了数值,以秒为单位。

rollback-for:用于指定一个异常,当产生该异常时,事务回滚,产生其他异常时,事务不回滚。没有默认值。表示任何异常都回滚。

no-rollback-for:用于指定一个异常,当产生该异常时,事务不回滚,产生其他异常时事务回滚。没有默认值。表示任何异常都回滚。

<!-- 2、配置事务的通知  -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <!-- 配置事务的属性-->
   <tx:attributes>
        <tx:method name="transfer" isolation="DEFAULT" propagation="REQUIRED" 
                   read-only="false"/>
   </tx:attributes>
</tx:advice>

3、基于注解的声明式事务

3.1、配置事务管理器

<!--  1、配置事务管理器  -->
<bean id="transactionManager" 																																				class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
</bean>

3.2、在业务类添加注解

@Service("accountService")
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;

3.3、配置JdbcTemplate模板

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

3.4、在Dao类添加注解

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;
}

3.5、配置类中扫描包

<context:component-scan base-package="cn.bdqn"/>

3.6、开启spring对注解事务的支持

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

3.7、在业务层@Transactional注解

@Service("accountService")
@Transactional
public class AccountServiceImpl implements AccountService {

    @Autowired
    private AccountDao accountDao;
}

3.8、测试

@Test
public void testTransfer() throws Exception{

        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        AccountService accountService = (AccountService) ac.getBean("accountService");
        accountService.transfer(1,2,100);
}


在这里插入图片描述

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

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

相关文章

集创赛Robei杯——Robei八角板7020简介

官方介绍 若贝八角板是一款FPGA开发板&#xff0c;可以用于系统设计与教育教学、竞赛、IC验证、系统控制、挖矿、云计算等用途&#xff0c;板子整体呈现正八角形&#xff0c;尺寸非常小&#xff0c;68x68mm&#xff0c;手掌心大小。虽然板子很小&#xff0c;但是功能齐全&#…

数据结构(邓俊辉)学习笔记——向量vector_01_接口与实现

文章目录 0.意图1、概述2 从数组到向量3 向量ADT接口4 Vector 模板类5 构造与析构5.1默认构造方法5.2基于复制的构造方法5.3 析构方法 0.意图 一方面是将工作学习中零星的知识点串起来&#xff0c;另一方面向量是其他数据类型的基础&#xff0c;比如栈队列等&#xff0c;所以基…

五种服务异步通信(MQ)-详解、代码案例

简介&#xff1a;本篇文章主要是介绍了常用的异步通信原理&#xff0c;主要是RabbitMQ技术 目录 1、初始MQ&#xff08;异步通讯&#xff09; 1.1 同步通讯 1.2 异步通讯 1.3 MQ常见框架 2、RabbitMQ快速入门 2.1 RabbitMQ概述和安装 2.2 常见消息模型 2.3 快速入门 3、…

【华为 ICT HCIA eNSP 习题汇总】——题目集18

1、SSH默认工作使用的TCP端口号是&#xff08;&#xff09;。 A、20 B、21 C、22 D、23 考点&#xff1a;①传输层 ②应用层 解析&#xff1a;&#xff08;C&#xff09; SSH为建立在应用层和传输层上的安全协议&#xff0c;是对TCP/IP协议的传输层以上的SSH会话流程进行加密的…

数字时代的社交王者:探索Facebook的社交帝国

引言&#xff1a;社交媒体的霸主 在数字化浪潮席卷全球的当下&#xff0c;社交媒体已然成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook则是这个领域的不二之选。作为全球最大的社交网络&#xff0c;Facebook不仅拥有庞大的用户群体&#xff0c;更在技术创新、社会…

System Dashboard for Mac:强大的系统监控与管理工具

System Dashboard for Mac是一款专为苹果电脑设计的系统监控与管理工具&#xff0c;以其直观易用的界面和全面的功能&#xff0c;深受用户喜爱。 System Dashboard for Mac v1.10.11激活版下载 这款软件能够实时监测系统的重要参数&#xff0c;包括CPU使用率、内存利用率、硬盘…

Acer宏碁掠夺者战斧300笔记本电脑PH315-52工厂模式原装Win10系统安装包 恢复出厂开箱状态 带恢复重置

宏碁掠夺者PH315-52原厂Windows10工厂包镜像下载&#xff0c;预装oem系统 链接&#xff1a;https://pan.baidu.com/s/1grmJzz6nW1GOaImY_ymXGw?pwdi286 提取码&#xff1a;i286 原厂W10系统自带所有驱动、PredatorSense风扇键盘控制中心、Office办公软件、出厂主题壁纸、系统…

OpenHarmony开发实例:【电话簿联系人Contacts】

样例简介 Contacts应用是基于OpenHarmony SDK开发的安装在润和HiSpark Taurus AI Camera(Hi3516d)开发板标准系统上的应用&#xff1b;应用主要功能是展示联系人列表&#xff0c;并点击某一列弹出联系人详细信息&#xff1b; 运行效果 样例原理 样例主要有一个list组件和dia…

unknown option ‘--variant=xxx‘

进行react native开发&#xff0c;启动项目时&#xff0c;出现如上报错时&#xff0c;试着用‘mode’代替variant即可 详细说明&#xff1a; 修改scripts命令&#xff0c;加入–variantdevDebug 终端运行对应命令,报如下的错 error: unknown option --variantdevDebug如图&am…

个人网站的SEO优化系列——如何实现搜索引擎的收录

如果你自己做了一个网站&#xff0c;并且想让更多的人知道你的网站&#xff0c;那么无非就是两种途径 一、自己进行宣传&#xff0c;或者花钱宣传 二、使用搜索引擎的自然流量 而如果搜索引擎都没有收录你的站点&#xff0c;别说是自然流量&#xff0c;就算是使用特定语句【sit…

在誉天学习云计算HCIE,担心考试考不过?

誉天定制化课程内容覆盖了所有考试重点&#xff0c;可以系统地掌握理论与实践知识。 对于笔试&#xff0c;类似于备考驾照理论学习阶段&#xff0c;誉天为大家提供在线模拟测试系统&#xff0c;帮助大家掌握云计算笔试考点。笔试通过后&#xff0c;18个月内&#xff08;一年半…

函数模版实例化

目录 一、前言 二、 什么是C模板 &#x1f4a6;泛型编程的思想 &#x1f4a6;C模板的分类 三、函数模板 &#x1f4a6;函数模板概念 &#x1f4a6;函数模板格式 &#x1f4a6;函数模板的原理 &#x1f4a6;函数模板的实例化 &#x1f34e;隐式实例化 &#x1f349;显式实例化 …

Pytorch下张量的形状操作(详细)

目录 一、基本操作函数 二、分类&#xff1a;维度改变&#xff0c;张量变形&#xff0c;维度重排 2.1维度改变 2.2张量变形 2.3维度重排 三、实例 一、基本操作函数 在PyTorch中&#xff0c;对张量的形状进行操作是常见的需求&#xff0c;因为它允许我们重新组织、选择和…

53、图论-课程表

思路&#xff1a; 其实就是图的拓扑排序&#xff0c;我们可以构建一个图形结构&#xff0c;比如[0,1]表示1->0&#xff0c;对于0来说入度为1。 遍历结束后&#xff0c;从入度为0的开始遍历。引文只有入度为0的节点没有先决条件。然后依次减少1。直到所有节点入度都为0.然后…

Ai-WB2 系列模组SDK接入亚马逊云

文章目录 前言一、准备二、亚马逊云物模型建立1. 注册亚马逊账号&#xff0c;登录AWS IoT控制台&#xff0c;[注册地址](https://aws.amazon.com/cn/)2. 创建好之后点击登录3. 创建物品以及下载证书 三、连接亚马逊云demo获取以及配置1. 下载源码2. 按照顺序执行下面指令3. 修改…

Tensorflow AutoGraph 的作用和功能

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ TensorFlow AutoGraph 是 TensorFlow 中的一个重要特性&#xff0c;它允许开发者使用普通的 Python 语法编写高效的 TensorFlow 图&#xff08;graph&#xff09;。这意味着开发者可以利用 Python 的易…

【51单片机项目】基于51单片机自制多功能小键盘/模拟USB键盘【附源码】(STC89C52RC+CH9328)

目录 一、效果展示 二、创作灵感 三、硬件电路 注意事项 工作原理 四、源码 main.c 五、附录 CH9328工作原理 CH9328的模式选择 ​编辑 全键盘键码值表 参考链接 一、效果展示 该小键盘具有三种功能&#xff1a; 1、自动输入开机密码 2、每隔一段时间自动按下ct…

在Mac M1笔记本上跑大语言模型llama3的4个步骤?(install、pull、run、ask)

要点 Ollama一个功能强大的本地大语言模型LLM运行工具&#xff0c;支持很多模型&#xff0c;并且操作极其简单快速回忆步骤&#xff1a; 下载ollama工具&#xff1a;https://ollama.com/download 下载模型&#xff1a;ollama pull llama3 #根据libs列表直接指定名字 运行模型…

【软考】设计模式之适配器模式

目录 1. 说明2. 应用场景3. 结构图4. 构成5. 优缺点5.1 优点5.2 缺点 6. 适用性7. java示例7.1 类适配器模式7.2 对象适配器模式 1. 说明 1.Adapter&#xff08;适配器&#xff09;。2.将一个类的接口转换成客户希望的另外一个接口。3.Adapter模式使得原本由于接口不兼容而不能…

visionTransformer window平台下报错

错误&#xff1a; KeyError: Transformer/encoderblock_0/MlpBlock_3/Dense_0kernel is not a file in the archive解决方法&#xff1a; 修改这个函数即可&#xff0c;主要原因是Linux系统与window系统路径分隔符不一样导致 def load_from(self, weights, n_block):ROOT f&…