1.事务
事务(Transaction)是数据库管理系统中的一个重要概念,它表示一组不可分割的操作序列,这些操作要么全部执行成功,要么全部不执行,以确保数据库从一个一致性状态转换到另一个一致性状态。事务具有以下四个基本特性,通常被称为ACID特性.
2. ACID特性
原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成,不会结束在中间某个点。
一致性(Consistency):事务必须使数据库从一个一致性状态转换到另一个一致性状态。也就是说,事务执行的结果必须符合所有预定义的规则和约束,例如数据的完整性和业务规则
比如:(转账:我有100 张三也有100,我和张三两个人的钱总数是200,这时张三转账给我50,张三只剩50,而我收款了有了150,那么我们两个人加起来的钱还是200,不管谁转给谁总数是不变的)
隔离性(Isolation):并发执行的事务之间不会互相影响。事务的隔离性描述了多个事务并发执行时,事务之间的相互影响程度。不同的数据库系统可能提供不同级别的隔离性,例如读未提交(Read
Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable
Read)和串行化(Serializable)。
持久性(Durability):一旦事务被提交,它对数据库所做的更改就是永久性的。即使系统发生故障,事务的结果也不会丢失。
3. 事务注解@Transactional
事务注解标注的地方:
1.类:当把@Transactional 注解放在类上时,表示所有该类的public方法都配置相同的事务属性信息,会导致事务控制的粒度太大,注解参数无法根据每个类方法的实际需求设置;因此,一般@Transactional注解都会直接添加的需要的方法上;
2. 方法: 当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息;
3. 接口:不推荐这种使用方法,因为一旦标注在Interface上并且配置了Spring AOP 使用CGLib动态代理,将会导致@Transactional注解失效;
4. @Transactional注解两个属性
rollbackFor属性:rollbackFor属性指定遇到什么类型的异常就进行回滚,默认是RuntimeException
propagation属性:propagation属性用于设置事务的椽笔级别,默认的级别就是REQUIRED
5. 事务的传播级别
在Spring框架中,事务管理是通过声明式事务管理来实现的,它允许我们以声明的方式配置事务。Spring事务的传播级别(Propagation
Levels)定义了事务的边界和范围,即当一个事务方法被另一个事务方法调用时,事务如何被传播。Spring定义了7种事务传播级别,它们分别如下:
REQUIRED:表示当前方法必须在一个具有事务的上下文中运行,如有客户端有事务在进行,那么被调用端将在该事务中运行,否则的话重新开启一个事务。(如果被调用端发生异常,那么调用端和被调用端事务都将回滚)
SUPPORTS:表示当前方法不必需要具有一个事务上下文,但是如果有一个事务的话,它也可以在这个事务中运行,没有事务则已非事务执行,就是纯方法
MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,就抛出异常。表示当前方法必须在一个事务中运行,如果没有事务,将抛出异常
REQUIRES_NEW:新建事务,如果当前存在事务,就把当前事务挂起。这是用于需要创建独立事务的方法。表示当前方法必须运行在它自己的事务中。一个新的事务将启动,而且如果有一个现有的事务在运行的话,则这个方法将在运行期被挂起,直到新的事务提交或者回滚才恢复执行。
NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,就把当前事务挂起。
NEVER:以非事务方式执行,如果当前存在事务,就抛出异常。
NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,行为与REQUIRED相同。表示如果当前方法正有一个事务在运行中,则该方法应该运行在一个嵌套事务中,被嵌套的事务可以独立于被封装的事务中进行提交或者回滚。如果封装事务存在,并且外层事务抛出异常回滚,那么内层事务必须回滚,反之,内层事务并不影响外层事务。如果封装事务不存在,则同PROPAGATION_REQUIRED的一样
6. 事务流程图
Spring AOP将通用的功能横向抽取出来作为切面,避免非业务代码侵入到业务代码中;通过@Transactional注解就能让Spring为我们管理事务,免去了重复的事务管理逻辑,减少对业务代码的侵入,让开发人员能够专注于业务层面开发;【这里我们知道事务时基于spring中的AOP(切面)进行实现的】
7. 必要依赖
<dependency>
<!--mysql连接依赖-->
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
</dependency>
<!-- druid连接池依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.23</version>
</dependency>
<!--spring框架依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.1.12</version>
</dependency>
<!--spring框架操作使用jdb操作数据库依赖(包括了事务(spring-tx)依赖)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.1.12</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>