80.【Spring5】(八)

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
简介: 80.【Spring5】

(十五)、事务回顾

1.回顾事务

  • 把一组业务当成一个业务来做;要么都成功,要么都失败
  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎
  • 确保完整性和一致性
(1).ACID
  • 原子性
  • 一致性
  • 隔离性:多个数据操作同一个资源
  • 持久性: 事务一旦提交,结果都不会再影响

2.Spring的增删改业务实现

实体类

package Com.Jsxs.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private int id;
    private String name;
    private String pwd;
}

接口

package Com.Jsxs.Mapper;
import Com.Jsxs.pojo.User;
import java.util.List;
public interface UserMapper {
//    查询所有的用户
    List<User> selectUser();
//    添加一个用户
    int addUser(User user);
//    删除一个用户
    int deleteUser(int id);
}

接口实现类

package Com.Jsxs.Mapper;
import Com.Jsxs.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
//    进行全部信息的查询
    @Override
    public List<User> selectUser() {
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
        User user = new User(7,"说的","54545");
        mapper.addUser(user);
        mapper.deleteUser(7);
        return mapper.selectUser();
    }
//    进行数据的添加
    @Override
    public int addUser(User user) {
        return getSqlSession().getMapper(UserMapper.class).addUser(user);
    }
//   进行数据的删除
    @Override
    public int deleteUser(int id) {
        return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
    }
}

接口配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Com.Jsxs.Mapper.UserMapper">
<!--    进行数据的全部信息查询-->
    <select id="selectUser" resultType="Com.Jsxs.pojo.User">
        select *from mybatis.user
    </select>
<!-- 进行数据的添加-->
    <insert id="addUser" parameterType="Com.Jsxs.pojo.User">
        insert into user values(#{id},#{name},#{pwd})
    </insert>
<!--  进行数据的删除  -->
    <delete id="deleteUser" parameterType="int">
        delete from user where id=#{id}
    </delete>
</mapper>

mybatis核心文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置文件-->
<configuration>
</configuration>

spring核心文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
">
<!--
DateSource: 使用Spring的数据源替换MyBatis的配置
我们这里使用Spring-Jdbc依赖提供的类 : org.springframework.jdbc.datasource.DriverManagerDataSource
-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;charEncoding=UTF8"/>
        <property name="username" value="root"/>
        <property name="password" value="121788"/>
    </bean>
    <!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"/>
        <!--   绑定mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:Com/Jsxs/Mapper/*.xml"/>
    </bean>
    <!--    SqlSessionTemplate: 就是我们需要用的sqlSession-->
<!--    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
<!--        &lt;!&ndash;       只能利用构造器注入 sqlSessionFactory,因为他没有set方法&ndash;&gt;-->
<!--        <constructor-arg index="0" ref="sqlSessionFactory"/>-->
<!--    </bean>-->
</beans>

汇总文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
">
    <import resource="spring-dao.xml"/>
    <!--创建bean1-->
    <bean id="user1" class="Com.Jsxs.Mapper.UserMapperImpl">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
</beans>

测试

import Com.Jsxs.Mapper.UserMapper;
import Com.Jsxs.pojo.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class MyTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        UserMapper user1 = context.getBean("user1", UserMapper.class);
        List<User> userList = user1.selectUser();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

3.继承SqlSessionDaoSupport

  • 在spring核心文件中可以不用写第三个factory的豆
  • 自动帮我们进行提交事务,不用手动提交了

4.Spring声明事务

Spring中的事务管理

  • 声明式事务: AOP
  • 编程式事务:需要在代码中进行事务的管理
(1).基本要求
(1).接口
package Com.Jsxs.Mapper;
import Com.Jsxs.pojo.User;
import java.util.List;
public interface UserMapper {
//    查询所有的用户
    List<User> selectUser();
//    添加一个用户
    int addUser(User user);
//    删除一个用户
    int deleteUser(int id);
}
(2).mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="Com.Jsxs.Mapper.UserMapper">
<!--    进行数据的全部信息查询-->
    <select id="selectUser" resultType="Com.Jsxs.pojo.User">
        select *from mybatis.user
    </select>
<!-- 进行数据的添加-->
    <insert id="addUser" parameterType="Com.Jsxs.pojo.User">
        insert into user values(#{id},#{name},#{pwd})
    </insert>
<!--  进行数据的删除  -->
    <delete id="deleteUser" parameterType="int">
        deletes from user where id=#{id}
    </delete>
</mapper>
(3).接口实现类【new】
mapper.addUser(user);
mapper.deleteUser(7);.
在select方法中进行添加和删除;
package Com.Jsxs.Mapper;
import Com.Jsxs.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper{
//    进行全部信息的查询
    @Override
    public List<User> selectUser() {
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
        User user = new User(7,"说的","54545");
        mapper.addUser(user);
        mapper.deleteUser(7);
        return mapper.selectUser();
    }
//    进行数据的添加
    @Override
    public int addUser(User user) {
        return getSqlSession().getMapper(UserMapper.class).addUser(user);
    }
//   进行数据的删除
    @Override
    public int deleteUser(int id) {
        return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
    }
}
(4).实体类
package Com.Jsxs.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
    private int id;
    private String name;
    private String pwd;
}
(5).mybatis核心文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置文件-->
<configuration>
</configuration>
(6).Spring核心文件【new】
(1).命令开启事务
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  <constructor-arg ref="datasource" />
</bean>
(2).结合Aop进行切面添加事务
(3).配置事务通知
<tx:advice id="txAdvice" transaction-manager="transactionManager">
(4).给哪些方法配置事务(需要添加约束) name: 需要添加事务接口的方法名 propagation 事务权限
 <tx:attributes>
            <tx:method name="addUser" propagation="REQUIRED"/>
            <tx:method name="deleteUser" propagation="REQUIRED"/>
            <tx:method name="selectUser" propagation="REQUIRED"/>
</tx:attributes>
(5).配置事务切入
<aop:config>
        <aop:pointcut id="pointcut" expression="execution(* Com.Jsxs.Mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
</aop:config>
<?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: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/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
">
<!--
DateSource: 使用Spring的数据源替换MyBatis的配置
我们这里使用Spring-Jdbc依赖提供的类 : org.springframework.jdbc.datasource.DriverManagerDataSource
-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;charEncoding=UTF8"/>
        <property name="username" value="root"/>
        <property name="password" value="121788"/>
    </bean>
    <!--sqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"/>
        <!--   绑定mybatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:Com/Jsxs/Mapper/*.xml"/>
    </bean>
    <!--    SqlSessionTemplate: 就是我们需要用的sqlSession-->
<!--    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
<!--        &lt;!&ndash;       只能利用构造器注入 sqlSessionFactory,因为他没有set方法&ndash;&gt;-->
<!--        <constructor-arg index="0" ref="sqlSessionFactory"/>-->
<!--    </bean>-->
<!--    配置声明式事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <constructor-arg ref="datasource" />
    </bean>
<!--    结合AOP实现事物的植入-->
<!--配置事务通知:-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--
    给哪些方法进行配置事务
    配置事务的传播特性: propagation
    name: 指向配置事务的方法名
-->
        <tx:attributes>
            <tx:method name="addUser" propagation="REQUIRED"/>
            <tx:method name="deleteUser" propagation="REQUIRED"/>
<!--            <tx:method name="update" propagation="REQUIRED"/>-->
            <tx:method name="selectUser" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
<!--    配置事务切入-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* Com.Jsxs.Mapper.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>
</beans>
(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"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
">
    <import resource="spring-dao.xml"/>
    <!--创建bean1-->
    <bean id="user1" class="Com.Jsxs.Mapper.UserMapperImpl">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
</beans>
(8).测试
import Com.Jsxs.Mapper.UserMapper;
import Com.Jsxs.pojo.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class MyTest {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        UserMapper user1 = context.getBean("user1", UserMapper.class);
        List<User> userList = user1.selectUser();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

(9).效果展示

我们因为对查询的方法进行了切面(AOP)的操作,并且我们给事务增加,删除和查询都进行事务的管理,添加了事务。所以我们在进行设置查询的时候;查询的方法内涵着(添加和删除),我们故意在删除的时候埋下埋伏,验证成功事务设置成功;不会添加信息7

5.为什么要使用事务

  1. 如果不配置事务,可能存在数据提交不一致的情况
  2. 如果我们不在Spring中去配置声明式事务,我们就需要在代码中进行手动
  3. 事务在项目中十分重要,涉及到数据的一致性和完整性问题,不能马虎。
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
24天前
|
人工智能 自然语言处理 Shell
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
本教程指导用户在开源AI助手Clawdbot中集成阿里云百炼API,涵盖安装Clawdbot、获取百炼API Key、配置环境变量与模型参数、验证调用等完整流程,支持Qwen3-max thinking (Qwen3-Max-2026-01-23)/Qwen - Plus等主流模型,助力本地化智能自动化。
34037 135
🦞 如何在 OpenClaw (Clawdbot/Moltbot) 配置阿里云百炼 API
|
6天前
|
人工智能 自然语言处理 监控
OpenClaw skills重构量化交易逻辑:部署+AI全自动炒股指南(2026终极版)
2026年,AI Agent领域最震撼的突破来自OpenClaw(原Clawdbot)——这个能自主规划、执行任务的智能体,用50美元启动资金创造了48小时滚雪球至2980美元的奇迹,收益率高达5860%。其核心逻辑堪称教科书级:每10分钟扫描Polymarket近千个预测市场,借助Claude API深度推理,交叉验证NOAA天气数据、体育伤病报告、加密货币链上情绪等多维度信息,捕捉8%以上的定价偏差,再通过凯利准则将单仓位严格控制在总资金6%以内,实现低风险高频套利。
3023 14
|
19天前
|
人工智能 安全 机器人
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI助手,支持钉钉、飞书等多平台接入。本教程手把手指导Linux下部署与钉钉机器人对接,涵盖环境配置、模型选择(如Qwen)、权限设置及调试,助你快速打造私有、安全、高权限的专属AI助理。(239字)
7386 21
OpenClaw(原 Clawdbot)钉钉对接保姆级教程 手把手教你打造自己的 AI 助手
|
18天前
|
人工智能 机器人 Linux
OpenClaw(Clawdbot、Moltbot)汉化版部署教程指南(零门槛)
OpenClaw作为2026年GitHub上增长最快的开源项目之一,一周内Stars从7800飙升至12万+,其核心优势在于打破传统聊天机器人的局限,能真正执行读写文件、运行脚本、浏览器自动化等实操任务。但原版全英文界面对中文用户存在上手门槛,汉化版通过覆盖命令行(CLI)与网页控制台(Dashboard)核心模块,解决了语言障碍,同时保持与官方版本的实时同步,确保新功能最快1小时内可用。本文将详细拆解汉化版OpenClaw的搭建流程,涵盖本地安装、Docker部署、服务器远程访问等场景,同时提供环境适配、问题排查与国内应用集成方案,助力中文用户高效搭建专属AI助手。
5178 12
|
20天前
|
人工智能 机器人 Linux
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手
OpenClaw(原Clawdbot)是一款开源本地AI智能体,支持飞书等多平台对接。本教程手把手教你Linux下部署,实现数据私有、系统控制、网页浏览与代码编写,全程保姆级操作,240字内搞定专属AI助手搭建!
5929 23
保姆级 OpenClaw (原 Clawdbot)飞书对接教程 手把手教你搭建 AI 助手