当前位置: 首页 > news >正文

spring —— 事务管理器

事务管理主要针对数据源进行操作:在数据库方面,通过 TransactionManager 事务管理器进行管理,表明一旦出现错误,该数据源的所有数据全部复原。那么数据库如何判断是否发生了错误呢?这就需要在代码方面,通过 @Transactional 注解管理相应的方法,表示一旦该方法出现错误,那么由该方法调用的数据就要执行回滚。

一、spring-config.xml 文件配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:tx="http://www.springframework.org/schema/tx"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--扫描组件--><context:component-scan base-package="com.spring.book"></context:component-scan><!--引入外部文件--><context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder><!--使用druid工具配置数据源--><bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="url" value="${jdbc.url}"></property><property name="driverClassName" value="${jdbc.driver}"></property><property name="username" value="${jdbc.user}"></property><property name="password" value="${jdbc.password}"></property></bean><!--将数据源作为属性传入JDBCTemplate对象--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="druidDataSource"></property></bean><!--将数据源作为属性传入DataSourceTransactionManager事务管理器对象--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="druidDataSource"></property></bean><!--启用事务管理器注解--><tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

二、数据库 

balance 设置为“无符号”,也就是不能为负数。 

三、java 代码

 Dao 层类:

package com.spring.book;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;@Component
public class BookDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public Integer getPriceByBookId(Integer bookId){String sql = "select price from book where bookid=?";return jdbcTemplate.queryForObject(sql, Integer.class, bookId);}public void updateStock(Integer bookId){String sql = "update book set stock=stock-1 where bookid=?";jdbcTemplate.update(sql, bookId);}public void updateBalance(Integer userId, Integer price){String sql = "update user set balance=balance-? where userid=?";jdbcTemplate.update(sql, price, userId);}
}

Service 类:

package com.spring.book;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class BookService {@Autowiredprivate BookDao bookDao;public void buyBook(Integer bookId, Integer userId){Integer price=bookDao.getPriceByBookId(bookId);bookDao.updateStock(bookId);bookDao.updateBalance(userId,price);}
}

Controller 类:

package com.spring.book;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class BookController {@Autowiredprivate BookService bookService;public void buyBook(Integer bookId, Integer userId){bookService.buyBook(bookId,userId);}
}

测试类:

import com.spring.book.BookController;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.transaction.annotation.Transactional;@SpringJUnitConfig(locations = "classpath:bean-jdbc.xml")
public class TxByAnnotationTest {@Autowiredprivate BookController bookController;@Test@Transactionalpublic void testBuyBook(){bookController.buyBook(1,1);}
}

 四、说明

该案例模拟 user 从 book 列表中买书的过程,如果交易成功,book 的库存减少 1,user 的资金减少相应的价格。如果不添加事务管理的话,Dao 层的各个方法是互不影响的,会出现资金不减少,但库存减少的情况,因此需要将这些方法作为一个统一的整体。此时可以将 @Transactional 注解添加在 Service 层、Controller 层或者 Test 层均可实现效果,也就是说受到 @Transactional 注解影响到的方法一旦出现错误,那么该方法调用的数据都将恢复原状。而究竟是哪些数据,则由 spring-config.xml 配置文件的 TransactionManager 确定。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Python - 开源库 ReportLab 库合并 CVS 和图像生成 PDF 文档
  • [网络编程】网络编程的基础使用
  • 【Drools】(二)基于业务需求动态生成 DRL 规则文件:事实与动作定义详解
  • Apache ShardingSphere Proxy5.5.0实现MySQL分库分表与读写分离
  • Halcon学习之边缘扩展
  • Java代理模式详解
  • React 的 KeepAlive 实战指南:深度解析组件缓存机制
  • 【网络爬虫技术】(1·绪论)
  • 深度学习高效性网络
  • 2024钉钉杯B题医疗门诊患者及用药数据案例分析
  • SolidWorks设计库的应用
  • 基于Golang+Vue3快速搭建的博客系统
  • 顺序表和单链表的代码实现
  • Ubuntu22.04安装Go语言的几种方式
  • Nginx系列-12 Nginx使用Lua脚本进行JWT校验
  • CentOS6 编译安装 redis-3.2.3
  • docker python 配置
  • js递归,无限分级树形折叠菜单
  • node入门
  • npx命令介绍
  • PAT A1120
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • quasar-framework cnodejs社区
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • 腾讯大梁:DevOps最后一棒,有效构建海量运营的持续反馈能力
  • 我有几个粽子,和一个故事
  • 用element的upload组件实现多图片上传和压缩
  • FaaS 的简单实践
  • 阿里云ACE认证学习知识点梳理
  • (06)金属布线——为半导体注入生命的连接
  • (175)FPGA门控时钟技术
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (3)nginx 配置(nginx.conf)
  • (LeetCode C++)盛最多水的容器
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • (附源码)ssm教材管理系统 毕业设计 011229
  • (回溯) LeetCode 40. 组合总和II
  • (译) 函数式 JS #1:简介
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • ***测试-HTTP方法
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • 、写入Shellcode到注册表上线
  • .md即markdown文件的基本常用编写语法
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别
  • .net(C#)中String.Format如何使用
  • .NetCore发布到IIS
  • .NET开源快速、强大、免费的电子表格组件
  • .Net中的集合
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @angular/cli项目构建--http(2)
  • @Conditional注解详解
  • @Service注解让spring找到你的Service bean
  • @Transactional类内部访问失效原因详解
  • @Value读取properties中文乱码解决方案