深入理解 Spring 事务:入门、使用、原理

Spring 事务是复杂一致性业务必备的知识点,掌握好 Spring 事务可以让我们写出更好地代码。这篇文章我们将介绍 Spring 事务的诞生背景,从而让我们可以更清晰地了解 Spring 事务存在的意义。

接着,我们会介绍如何快速使用 Spring 事务。接着,我们会介绍 Spring 事务的一些特性,从而帮助我们更好地使用 Spring 事务。最后,我们会总结一些 Spring 事务常见的问题,避免大家踩坑。

Spring 事务 - 思维导图

诞生背景

当我们聊起事务的时候,我们需要明白「事务」这个词代表着什么。

事务其实是一个并发控制单位,是用户定义的一个操作序列,这些操作要么全部完成,要不全部不完成,是一个不可分割的工作单位。事务有 ACID 四个特性,即:

  • Atomicity(原子性):事务中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。
  • 一致性(Consistency):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。
  • 事务隔离(Isolation):多个事务之间是独立的,不相互影响的。
  • 持久性(Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

而我们说的 Spring 事务,其实是事务在 Spring 中的实现。

明白了什么是事务之后,我们来聊聊:为什么要有 Spring 事务?

为了解释清楚这个问题,我们举个简单的例子:银行里树哥要给小黑转 1000 块钱,这时候会有两个必要的操作:

  • 将树哥的账户余额减少 1000 元。
  • 将小黑的账户余额增加 1000 元。

这两个操作,要么一起都完成,要么都不完成。如果其中某个成功,另外一个失败,那么就会出现严重的问题。而我们要保证这个操作的原子性,就必须通过 Spring 事务来完成,这就是 Spring 事务存在的原因。

如果你深入了解过 MySQL 事务,那么你应该知道:MySQL 默认情况下,对于所有的单条语句都作为一个单独的事务来执行。我们要使用 MySQL 事务的时候,可以通过手动提交事务来控制事务范围。Spring 事务的本质,其实就是通过 Spring AOP 切面技术,在合适的地方开启事务,接着在合适的地方提交事务或回滚事务,从而实现了业务编程层面的事务操作。

使用指南

Spring 事务支持两种使用方式,分别是:声明式事务(注解方式)、编程式事务(代码方式)。一般来说,我们使用声明式事务比较多,这里我们就演示声明式事务的使用方法。

项目准备

为了较好地进行讲解,我们需要搭建一个具备数据库 CURD 功能的项目,并创建 tablea 和 tableb 两张表。

首先,创建 tablea 和 tableb 两张表,两张表都只有 id 和 name 两列,建表语句如下图所示。

CREATE TABLE `tablea` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1;
CREATE TABLE `tableb` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1;

接着,创建一个 SpringBoot 项目,随后加入 MyBatis 及 MySQL 的 POM 依赖。

<dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
 <groupId>org.mybatis.spring.boot</groupId>
 <artifactId>mybatis-spring-boot-starter</artifactId>
 <version>2.1.0</version>
</dependency>

最后,我们创建对应的 controller 接口、service 接口、mapper 接口,代码如下所示。

创建 controller 接口:

@SpringBootApplication
@RestController
@RequestMapping("/api")
public class SpringTransactionController {

    @Autowired
    private TransactionServiceA transactionServiceA;

    @RequestMapping("/spring-transaction")
    public String testTransaction() {
        transactionServiceA.methodA();
        return "SUCCESS";
    }
}

创建 TableService 接口。

public 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值