Spring事务简介及相关案例

这篇具有很好参考价值的文章主要介绍了Spring事务简介及相关案例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

 

一、事务简介

二、准备数据库

三、创建maven项目,引入依赖和完成相关配置

1. pom.xml文件

2. 创建配置文件

四、编写Java代码

1. Account实体类

2. AccountDao接口

3. AccountService业务类 

五、测试

1. 测试方法

2. 测试结果​编辑

往期专栏&文章相关导读 

1. Maven系列专栏文章

2. Mybatis系列专栏文章

3. Spring系列专栏文章 


一、事务简介

        事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transactionend transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

        事务:不可分割的原子操作。即一系列的操作要么同时成功,要么同时失败。

        开发过程中,事务管理一般在service层,service层中可能会操作多次数据库,这些操作是不可分割的。否则当程序报错时,可能会造成数据异常。
        如:张三给李四转账时,需要两次操作数据库:张三存款减少、李四存款增加。如果这两次数据库操作间出现异常,则会造成数据错误。

二、准备数据库

        读者把下面代码段复制粘贴到文本,然后把后缀名改为sql,就是sql文件了,然后打开数据库运行数据库脚本即可。这里就一个表,字段有id,用户名,余额。

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for account
-- ----------------------------
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `balance` double NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of account
-- ----------------------------
INSERT INTO `account` VALUES (1, '张三', 1000);
INSERT INTO `account` VALUES (2, '李四', 1000);

SET FOREIGN_KEY_CHECKS = 1;

三、创建maven项目,引入依赖和完成相关配置

        这里我们需要引入的依赖有:mysql驱动包,druid连接池,spring依赖,MyBatis与Spring的整合包,该包可以让Spring创建MyBatis的对象,junit测试,spring整合测试模块依赖的依赖。

1. pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>spring_transfer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!--  mybatis  -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.1.1</version>
        </dependency>
        <!--  mysql驱动包  -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>
        <!--  druid连接池  -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <!-- spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.13</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.13</version>
        </dependency>

        <!-- MyBatis与Spring的整合包,该包可以让Spring创建MyBatis的对象 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.13</version>
        </dependency>
        <!--  AspectJ    -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.7</version>
        </dependency>
        <!-- junit,如果Spring5整合junit,则junit版本至少在4.12以上 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- spring整合测试模块 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.3.13</version>
            <scope>test</scope>
        </dependency>
    </dependencies>


</project>

2. 创建配置文件

        配置文件主要用于数据库的连接,还有bean对象的建立,如下就是applicationContext.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:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:http="http://www.springframework.org/schema/p"
        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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 包扫描 -->
    <context:component-scan base-package="com.example"/>
    <!-- 创建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:///spring"/>
        <property name="username" value="root"/>
        <property name="password" value="666666"/>
    </bean>

    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>

    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.example.dao"/>
    </bean>

</beans>

四、编写Java代码

这里同样是编写账户的实体类即可,然后还要写一个Dao接口,业务层。

1. Account实体类

package com.example.pojo;

public class Account {

    // 账号
    private int id;
    // 用户名
    private String username;
    // 余额
    private double balance;

    public Account() {
    }

    public Account(int id, String username, double balance) {
        this.id = id;
        this.username = username;
        this.balance = balance;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    @Override
    public String toString() {
        return "Account[ " +
                "id=" + id +
                ", username='" + username + '\'' +
                ", balance=" + balance +
                " ]";
    }
}

2. AccountDao接口

package com.example.dao;

import com.example.pojo.Account;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.stereotype.Repository;

@Repository
public interface AccountDao {

    // 根据id查找用户
    @Select("select * from account where id=#{id}")
    Account findById(int id);

    // 修改用户
    @Update("update account set balance = #{balance} where id = #{id}")
    void update(Account account);
}

3. AccountService业务类 

package com.example.service;

import com.example.dao.AccountDao;
import com.example.pojo.Account;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AccountService {
    @Autowired
    private AccountDao accountDao;

    /**
     *
     * @param id1 转出人id
     * @param id2 转入人id
     * @param price 金额
     */
    // 作用方法上时,该方法都将具有该类型事务的事务属性
    public void transfer(int id1,int id2, double price){

        // 转出人减少余额
        Account account1 = accountDao.findById(id1);
        account1.setBalance(account1.getBalance() - price);
        accountDao.update(account1);

        // 模拟程序出错
        int i = 1 / 0;

        // 转入人增加余额
        Account account2 = accountDao.findById(id2);
        account2.setBalance(account2.getBalance() + price);
        accountDao.update(account2);
    }

}

五、测试

1. 测试方法

import com.example.service.AccountService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class AccountServiceTest {
    @Autowired
    private AccountService accountService;

    @Test
    public void testTransfer(){
        accountService.transfer(1,2,500);
    }
}

2. 测试结果

 OK,可以看到这里程序是出现异常中断了的。 现在观看数据库里面的情况是怎么样的。

Spring事务简介及相关案例

        此时没有事务管理,会造成张三的余额减少,而李四的余额并没有增加。所以事务处理位于业务层,即一个service方法是不能分割的。 因此下一篇文章我们会学习到事务管理方案。一步步深入学习,期待大家的支持啊。 

往期专栏&文章相关导读 

     大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。文章来源地址https://www.toymoban.com/news/detail-475460.html

1. Maven系列专栏文章

Maven系列专栏 Maven工程开发
Maven聚合开发【实例详解---5555字】

2. Mybatis系列专栏文章

Mybatis系列专栏 MyBatis入门配置
Mybatis入门案例【超详细】
MyBatis配置文件 —— 相关标签详解
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填
Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分)
Mybatis分页查询——四种传参方式
Mybatis一级缓存和二级缓存(带测试方法)
Mybatis分解式查询
Mybatis关联查询【附实战案例】
MyBatis注解开发---实现增删查改和动态SQL
MyBatis注解开发---实现自定义映射关系和关联查询

3. Spring系列专栏文章 

Spring系列专栏 Spring IOC 入门简介【自定义容器实例】
IOC使用Spring实现附实例详解
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式
Spring DI简介及依赖注入方式和依赖注入类型
Spring IOC相关注解运用——上篇
Spring IOC相关注解运用——下篇
Spring AOP简介及相关案例
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】
Spring事务简介及相关案例
Spring 事务管理方案和事务管理器及事务控制的API
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

到了这里,关于Spring事务简介及相关案例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring MVC简介附入门案例

    目录   一、SpringMVC简介 1.1 MVC模型 1.2 SpringMVC 二、SpringMVC入门案例 2.1 创建项目 2.2 引入依赖和tomcat插件 2.3 修改web.xml文件  2.4 新建springmvc.xml文件 2.5 编写控制器  2.6 配置运行方式 2.7 运行测试  三、SpringMVC执行流程 3.1 SpringMVC的组件 3.2 组件的工作流程 往期专栏文章

    2024年02月09日
    浏览(57)
  • 【Spring教程30】Spring框架实战:从零开始学习SpringMVC 之 Rest风格简介与RESTful入门案例

    欢迎大家回到《Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》,本文的上一篇为《SpringMVC 之 服务器响应》 REST(Representational State Transfer),表现形式状态转

    2024年02月04日
    浏览(51)
  • AIGC:ChatGPT(一个里程碑式的对话聊天机器人)的简介(意义/功能/核心技术等)、使用方法(七类任务)、案例应用(提问基础性/事实性/逻辑性/创造性/开放性的问题以及编程相关)之详细攻略

    AIGC:ChatGPT(一个里程碑式的对话聊天机器人)的简介(意义/功能/核心技术等)、使用方法(七类任务)、案例应用(提问基础性/事实性/逻辑性/创造性/开放性的问题以及编程相关)之详细攻略 导读 :回拨到2020年5月,OpenAI提出了更强大的GPT-3模型,如今已经过去2年多了,当人们还在

    2024年02月03日
    浏览(50)
  • [笔记]事务简介-springboot

    在Spring Boot中,事务的管理通常通过注解来实现,使得配置变得简单而直观。这种方式与Spring Boot的设计理念一致,即减少显式配置,增加自动配置。以下是如何在Spring Boot项目中应用和管理事务的详细说明: Spring Boot事务基础 Spring Boot沿用了Spring的事务管理概念,但在配置和

    2024年01月25日
    浏览(31)
  • 事务相关概念

    事务:逻辑上的一组操作,这些操作要么都成功,有一个失败所有都失败 1、脏读:在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。 2、不可重复读:指在数据库访问中,一个事务范

    2023年04月17日
    浏览(29)
  • MySQL事务相关笔记

    InnoDB 最大特点:支持 事务 和 行锁 ; MyISAM 不支持事务 一个事务是由一条或者多条对数据库操作的SQL语句所组成的一个 不可分割 的单元,只有当事务中的所有操作都正常执行完了,整个事务才会被提交给数据库。事务有如下特性: 1.事务的所有SQL语句全部执行成功,才能提

    2024年02月09日
    浏览(30)
  • python 相关框架事务开启方式

    对于框架而言,各式API接口少不了伴随着事务的场景,下面就列举常用框架的事务开启方法 注:利用begin_nested方法,会开启一个子事务!实现数据库变更需将子事务提交再将主事务提交才行 2.1、样例模板 2.2、进化版

    2024年02月13日
    浏览(71)
  • 案例挑战——事务传播行为

    此前在项目开发过程中,使用到了事务的传播行为。但是大多数情况下都是使用的事务默认的传播行为required。但是其实还有其他的传播行为。所以特地的回顾和学习了事务的多种传播行为。本篇博客从5w2h的角度来对事务的传播行为进行学习和实践。 事务的传播行为其实指的

    2024年02月12日
    浏览(33)
  • Nginx目录结构简介:深入理解Nginx的默认文件和目录

    第一章 Nginx的默认目录结构 当你安装Nginx后,它的默认目录结构如下: 让我们逐个了解这些目录和文件的作用。 第二章 conf目录 conf目录包含了Nginx的配置文件,其中nginx.conf是Nginx主配置文件,它包含了所有全局的Nginx配置项。mime.types文件包含了MIME类型的定义,它告诉Nginx如

    2024年02月13日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包