【Spring】19 事务

19、Spring 事务管理与 MVC 框架入门 本文详细介绍了Spring框架中的事务管理和Spring MVC Web开发的基础知识。内容涵盖声明式事务的XML配置与注解驱动方式,以及Spring MVC的请求处理流程、基本配置和主页开发步骤。通过学习,开发者可以掌握构建企业级Java应用的关键技能,提高开发效率和应用质量。 阅读详情

JDBC连接

这个就不再赘述了,可以看一下【Spring】JDBC的支持

数据库表

CREATE TABLE `account` (
  `username` varchar(20) NOT NULL,
  `balance` int(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='账户表';

在这里插入图片描述

CREATE TABLE `book` (
  `isbn` int(10) NOT NULL,
  `book_name` varchar(20) NOT NULL,
  `price` double(10,2) NOT NULL,
  PRIMARY KEY (`isbn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

在这里插入图片描述

CREATE TABLE `book_stock` (
  `isbn` int(11) NOT NULL,
  `stock` int(11) NOT NULL,
  PRIMARY KEY (`isbn`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='书-库存表';

在这里插入图片描述

BookStockException.java(com.test.spring.tx.BookStockException)

package com.test.spring.tx;

public class UserAccountException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public UserAccountException() {
    }

    public UserAccountException(String message) {
        super(message);
    }

    public UserAccountException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserAccountException(Throwable cause) {
        super(cause);
    }

    public UserAccountException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

UserAccountException.java(com.test.spring.tx.UserAccountException)

package com.test.spring.tx;

public class UserAccountException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    public UserAccountException() {
    }

    public UserAccountException(String message) {
        super(message);
    }

    public UserAccountException(String message, Throwable cause) {
        super(message, cause);
    }

    public UserAccountException(Throwable cause) {
        super(cause);
    }

    public UserAccountException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

BookShopService.java(com.test.spring.tx.BookShopService)

package com.test.spring.tx;

public interface BookShopService {

    public void purchase(String username, String isbn);

}

BookShopServiceImpl.java(com.test.spring.tx.BookShopServiceImpl)

package com.test.spring.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService {

    @Autowired
    private BookShopDao bookShopDao;

    @Override
    public void purchase(String username, String isbn) {

        // 1. 获取书的单价
        int price = bookShopDao.findBookPriceByIsbn(isbn);

        // 2. 更新书的库存
        bookShopDao.updateBookStock(isbn);

        // 3. 更新用户余额
        bookShopDao.updateUserAccount(username, price);
    }
}

BookShopDao.java(com.test.spring.tx.BookShopDao)

package com.test.spring.tx;

public interface BookShopDao {

    // 根据书号获取书的单价
    public int findBookPriceByIsbn(String isbn);

    // 跟新书的库存,使书号对应的库存 -1
    public void updateBookStock(String isbn);

    // 更新用户的账户余额:使 username 的 balance - price
    public void updateUserAccount(String username, int price);
}

BookShopDaoImpl.java(com.test.spring.tx.BookShopDaoImpl)

package com.test.spring.tx;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository("bookShopDao")
public class BookShopDaoImpl implements BookShopDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public int findBookPriceByIsbn(String isbn) {
        String sql = "SELECT price FROM book WHERE isbn = ?";
        return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
    }

    @Override
    public void updateBookStock(String isbn) {
        // 检查书的库存是否足够,若不够,抛出异常
        String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";
        int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);
        if (stock == 0) {
            throw new BookStockException("库存不足!");
        }

        String sql = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?";
        jdbcTemplate.update(sql, isbn);
    }

    @Override
    public void updateUserAccount(String username, int price) {
        // 检查余额是否足够,若不够,抛出异常
        String sql2 = "SELECT balance FROM account WHERE username = ?";
        int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);
        if (balance < price) {
            throw new UserAccountException("余额不足!");
        }

        String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";
        jdbcTemplate.update(sql, price, username);
    }
}

StringTransactionTest.java(com.test.spring.tx.StringTransactionTest)

package com.test.spring.tx;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class StringTransactionTest {

    private ApplicationContext ctx = null;
    private BookShopDao bookShopDao = null;
    private BookShopService bookShopService = null;

    {
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        bookShopDao = ctx.getBean(BookShopDao.class);
        bookShopService = ctx.getBean(BookShopService.class);
    }

    @Test
    public void testBookShopService(){
        bookShopService.purchase("AA", "1001");
    }

    // 用户AA的账户余额减去100
    @Test
    public void testBookShopDaoUpdateUserAccount(){
        bookShopDao.updateUserAccount("AA", 100);
    }

    // isbn为1001的库存减一
    @Test
    public void testBookShopDapUpdateBookStock() {
        bookShopDao.updateBookStock("1001");
    }

    // 获取isbn为1001的价格
    @Test
    public void test() {
        System.out.println(bookShopDao.findBookPriceByIsbn("1001"));
    }
}

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"
       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/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="com.test.spring"></context:component-scan>

    <!-- 导入资源文件 -->
    <context:property-placeholder location="db.properties"></context:property-placeholder>

    <!-- 配置 C3P0 数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
        <property name="driverClass" value="${jdbc.driverClass}"></property>

        <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
        <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
    </bean>

    <!-- 配置 Spring 的 JDBCTemplate -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置 NamedParameterJdbcTemplate,该对象可以使用具名参数,其没有无参数的构造器,所有必须为其构造器指定参数 -->
    <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="dataSource"></constructor-arg>
    </bean>
</beans>

这样会有一个问题

如果钱不够的情况下执行,钱不会扣,但是书的数量会扣!
看下一篇【Spring】声明式事务

radsystems的激活(破解)和使用 上个文章讲述了radsystems的下载,但是只有30天的免费使用权,这篇文章将会讲解如何破解激活radsystems。注意:如果不想去官网下载的话,点击安装包的exe文件。不要急,打开我给你们的安装包,点击crack。如果提示done则完成(我的是激活过的)注意:这是8.7版本的。点击generate。 阅读详情

相关推荐

从ViT到CLIP:OpenAI如何用4亿张图‘教会’AI看懂世界?一次讲透对比学习与Prompt工程

本文深入解析OpenAI的CLIP模型如何通过4亿图文对的对比学习实现跨模态理解,详细探讨了对比学习、数据构建、模型架构及Prompt工程等核心技术。CLIP利用Transformer架构和精心设计的Prompt模板,在Zero-Shot分类、图像检索等场景展现出强大能力,为多模态AI应用开辟新方向。

weixin_27027459的博客 372

第19章 Spring事务王国的架构(五)

当然,这期间也会涉及事务定义的应用以及条件检查等逻辑。在所有一切搞定之后,newTransactionStatus会创建一个包含definition、transaction object以及挂起的事务信息和其他状态信息的DefaultTransactionStatus实例并返回。如果definition定义的传播行为是PROPAGATION_NESTED,根据情况创建嵌套事务,如通过Savepoint或者JTA的TransactionManager。如下: 在这种情况下,会首先通过方法检查AbstractP

hello world 11万+

实战指南(一)SCAPS-1D太阳能电池模拟软件从零到一:模型构建与参数解析

本文详细介绍了SCAPS-1D太阳能电池模拟软件的使用方法,从模型构建到参数解析,帮助用户快速掌握这一免费且功能强大的工具。特别适合用于单结/多结电池的电学性能分析,涵盖钙钛矿电池等常见结构的模拟实践,并提供参数调试和收敛性问题处理的实用技巧。

weixin_30588675的博客 445

spring揭秘19-spring事务01-事务抽象

1)spring对事务元素进行抽象, 客户端仅按照统一的编程模型管理事务,而不用关心数据访问技术以及具体要访问什么类型的事务资源;此外:spring事务管理与spring提供的数据访问技术(如JdbcTemplate)进行结合;2)spring事务框架设计的基本原则: 让事务管理逻辑与数据访问逻辑解耦;spring揭秘15-spring集成数据访问技术(orm框架)总结事务隔离级别;isolation;事务传播行为;事务超时时间;timeout;是否为只读事务;readOnly;

PacosonSWJTU的博客 1619

Field-Oriented Control (FOC) 矢量控制 磁场定向控制

Field-Oriented Control (FOC) 磁场定向控制(FOC),也称为矢量控制,是一种用于控制永磁同步电动机(PMSM)和交流感应电动机(ACIM)的技术。 FOC在整个扭矩和速度范围内都具有良好的控制能力。 FOC的实现需要将定子电流从固定参考系转换为转子磁通参考系(也称为d-q参考系)。 速度控制和转矩控制是FOC最常用的控制模式。位置控制模式不太常见。大多数牵引应用使用转矩控制模式,在该模式下,电动机控制系统遵循参考转矩值。在速度控制模式下,电机控制器遵循参考速度值,并生成用于形成内

>>> 1万+

从建模到调参:基于Simulink的两轮差速机器人轨迹跟踪PID控制全流程解析

本文详细解析了基于Simulink的两轮差速机器人轨迹跟踪PID控制全流程。从运动学建模入手,对比了基于距离与基于位置偏差的两种控制策略,并重点阐述了高精度轨迹跟踪的控制器设计、Simulink仿真搭建及PID参数整定方法,为移动机器人运动控制提供了完整的仿真实践指南。

weixin_29169505的博客 314

Spring19——Spring事务属性(事务配置、转账业务追加日志、事务传播行为)

Spring事务属性(事务配置、转账业务追加日志、事务传播行为)

后端小白个人学习记录 936

使用moveit控制机械臂

位置设置:`target_pose.position.x = 0.12`, `target_pose.position.y = 0.41`, 和 `target_pose.position.z = 0.44` 分别设置了机械臂末端执行器的X, Y, 和 Z坐标。设定目标位置:`group.set_pose_target(target_pose)` 这一命令将之前定义的目标位置和姿态设置为当前机械臂组的目标,为接下来的路径规划做准备。在机械臂控制的过程中,设定精确的目标位置和姿态是实现精确操作的关键步骤。

realman_Rop的博客 3688

Spring——19 声明式事务

1.编程式事务 概念:由程序员编程事务控制代码 举例:OpenSessionInView 2.声明式事务 概念: 事务控制代码已经由 spring 写好,程序员只需要声明出哪些方法需要进行事务控制和如何进行事务控制 声明式事务都是针对于 ServiceImpl 类下方法的 事务管理器基于通知(advice)的 在 spring 配置文件中配置声明式事务 事务管理器 声明哪些方法需要事务管理 基于...

Re_view的博客 317

智能车图像处理4-入门级分析3 ---十字路口补线

PS :入门级文章适合新手,如果已经有基础可以去看进阶篇文章。

taiyuezyh的博客 1万+

YOLOv11改进 | Conv/卷积篇 | 轻量化多尺度异构卷积(MSHC)优化YOLOv11精度(全网独家首发)

本文介绍了Hype-YOLO提出的MANet结构,这是C3、C2f、C3k2的升级版,能显著增强特征提取能力。MANet整合了DSConv和C2f结构,通过多分支异构设计提升梯度流动和特征语义深度。文章详细解析了MSHC模块的原理,包括其多尺度并行建模、通道混洗等核心机制,并提供了完整的代码实现和训练教程。实验表明,Hype-YOLO的精度优于YOLOv11。该结构在保持轻量化的同时,通过异构分支设计实现了更丰富的特征表达,适用于目标检测等视觉任务。

Snu77的博客 953

19.Spring的事务之数据库事务概述

1 数据库事务概述 事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务。 事务必需满足ACID(原子性、一致性、隔离性和持久性)特性,缺一不可: 原子性(Atomicity):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做; 一致性(Consistency):在事务执行前数据库的数据处于正确的状态...

anjunshuang 179

18、改进的LSTM用于污染物浓度预测

本文探讨了改进的长短期记忆网络(MLSTM)在空气污染预测中的应用,重点分析了其对印度泰米尔纳德邦五个城市(金奈、塞勒姆、哥印拜陀、马杜赖和图蒂科林)的PM2.5、PM10、SO2和NO2四种污染物浓度的预测效果。通过与传统LSTM模型的对比实验,结果显示MLSTM在预测准确性和执行效率方面均优于LSTM。研究结果表明,MLSTM在空气质量预测领域具有较高的应用潜力,可为环境保护和空气质量管理提供有力支持。

j0k1l2m3n的博客 175

第19章 Spring事务王国的架构(一)

本章内容统一中原的过程和平年代Spring的事务框架将开发过程中事务管理相关的关注点进行适当的分离,并对这些关注点进行合理的抽象,最终打造了一套使用方便,却功能强大的事务管理“利器”。通过Spring的事务框架,我们可以按照统一的编程模型来进行事务编程,却不用关心所使用的数据访问技术以及具体要访问什么类型的事务资源。并且,Spring的事务框架与Spring提供的数据访问支持可以紧密结合,更是让我们在事务管理与数据访问之间游刃有余。而最主要的是,结合Spring的AOP框架,Spring的事务框架为我们带来

hello world 11万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

19.spring中事务控制的API

参考的学习视频→https://b23.tv/av47952931/p82 Spring中事务控制需要的pom依赖 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <versio...

si_si_si的博客 171

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

第19章 Spring事务王国的架构(三)

org.springframework.transaction.TransactionStatus接口定义表示整个事务处理过程中的事务状态,更多时候,我们将在编程式事务中使用该接口。在事务处理过程中,我们可以使用TransactionStatus进行如下工作。使用TransactionStatus提供的相应方法查询事务状态。通过setRollbackOnly()方法标记当前事务以使其回滚。如果相应的PlatformTransactionManager支持Savepoint,可以通过TransactionSt

hello world 11万+

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

第19章 Spring事务王国的架构(四)

PlatformTransactionManager的各个子类在实现时,基本上遵循统一的结构和理念。所以,我们不妨选择以DataSourceTransactionManager这一实现类作为切入点,以管中窥豹之势,一探Spring的抽象事务框架中各个PlatformTransactionManager实现类的奥秘所在。不过,在开始之前,我们有必要先了解如下几个概念。将它们与JTA规范中定义的接口相提并论,是因为这些概念只限于局部场景中对应的PlatformTransactionManager实现类使用,而J

hello world 11万+

19-spring事务失效原因

解决方法:如果需要在捕获检查异常时回滚事务,需要在@Transactional注解中指定rollbackFor属性,包含需要回滚的异常类型。解决方法:确保@Transactional注解正确使用在需要事务的方法上,并且配置正确(如传播行为、隔离级别等)。解决方法:确保类不是final类,方法不是final方法,并且Spring能够通过CGLIB动态代理。解决方法:确保自调用方法也通过代理类调用,或者将注解移到代理类的方法上。解决方法:确保事务方法中的异常被抛出,或者在捕获异常后手动回滚事务。

weixin_41775999的博客 254

SSH与SSM学习之Spring19——Spring事务之事务基础

SSH与SSM学习之Spring19Spring事务之事务基础 一事务概念 二事务特性 1 原子性 2 一致性 3 隔离性 4 持久性 三事务并发问题 四解决读问题设置事务隔离级别 五事务操作 SSH与SSM学习之Spring19——Spring事务之事务基础一、事务概念事务是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成

qiwenmingshiwo的专栏 365

第19章 Spring事务王国的架构(二)

Spring的事务抽象包括3个主要接口,即PlatformTransactionManager、TransactionDefinition以及TransactionStatus,它们之间的关系如图19-4所示。这3个接口以PlatformTransactionManager为中心,互为犄角,多少有点儿“晋西北铁三角”的味道。PlatformTransactionManager负责界定事务边界。TransactionDefinition负责定义事务相关属性,包括隔离级别、传播行为等。PlatformTrans

hello world 11万+

Spring-事务支持 2021-09-19

Spring的基础和应用系列文章目录 第一部分 Spring 基础 1.1 XML使用-IoC配置与依赖(DI)配置 1.2 基于注解和XML混合方式的使用 1.3 基于纯注解方式的使用 1.4 AOP 介绍 1.5 Spring 整合AspectJ的AOP使用 第二部分 组件支持 2.1 Spring 整合Junit 2.2 Spring 事务支持 Spring 事务支持Spring的基础和应用系列文章目录一 事务回顾1.1 事务介绍1.2 事务并发问题(隔离性导致)1.3 事务隔离级别1.4 Sp

qq_21438267的博客 525

19-Spring中的事务属性(Transaction Attribute)

上一篇:18-Spring事务控制@Transactional https://blog.youkuaiyun.com/fsjwin/article/details/109497305 1.什么是事务属性 属性:描述事务特征的一系列值 性别、身高、年龄、体重等... ... 事务的属性:就是能在@Transactional(这个括内些的值),一以下为5中事务属性 1.隔离级别 2.传播行为 3.只读属性 4.超时属性 5.异常属性 下面的例子就是很好的说明: @Transactional( isol

前路无畏的博客 1万+

19-spring声明式事务详解

一 简介 @Transactional注解包含众多的属性,下面会依次介绍这些属性的作用 isolation 事务的隔离级别 propagation 事务的传播行为 timeout 事务超时时间 当事务执行超时后,会自动终止并回滚 秒为单位 readOnly 设置事务为只读事务 rollbackFor 哪些异常需要进行回滚(class 数组) rollbackForClassName 哪些异常需要进行回滚(String 数组) noRollbackFor 哪些异常事务可以不回滚(class 数组) noR

SO 204

19、(知识篇)Spring使用事务Transation

/** * spring事务管理: *  * 1、指定transactionmanager * * ref="dataSource"> * * * 2.1、指定通过注解设置事务 * * *  2.2、指定通过xml设置事务 *  使用xml配置服务 1、使用tx:advice指定需要使用事务的方法 1、1可以指定方法/匹配方法/* 设置需要使用事务 2

你的博客 525

Spring框架 (19) —— 数据库事务的隔离级别

数据库事务的隔离级别数据库事务的隔离级别解决丢失更新的方案Spring对事务的支持TransactionDefinition事务传播规则PlatformTransactionManager事务管理器PlatformTransactionManager事物管理器的继承体系图 数据库事务的隔离级别 问题:上述问题理论上如果出现了应该如何解决? 答:一般情况,数据库都会处理一些事务并发的问题,数据库提供...

NotaChtholly的博客 327

19.Spring_事务的传播行为以及其他属性

1.当事务方法被另一个事务方法调用的时候,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在自己的事务中运行。 2.事务的传播行为可以由传播属性指定,Spring定义了7种传播行为: required: 如果有事务在运行,则当前方法就在这个事务内运行,否则就新启动一个事务,并在自己的事务内运行(默认) required_new:当前方法必须启动新的事务,

a2181745的专栏 530
上一篇: 【Spring】JDBC的支持
下一篇: 【小技巧】关于Windows10跨桌面切换应用的使用
ZyhMemory
博客等级 码龄10年 43粉丝 165原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值