Spring事务管理

Spring 并不直接管理事务,而是提供了多种事务管理器。在实际开发中,操作数据库时都会涉及到事务管理问题,为此Spring提供了专门用于事务处理的API。Spring的事务管理简化了传统的事务管理流程,并且在一定程度上减少了开发者的工作量。

一、事务的特性

事务应该具有4个属性:原子性、一致性、隔离性、持久性。

1、原子性:一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

例如:A和B两个人一共1000元,A给B转账100元,A付款100元,B收款100元,

         A的付款行为和B的收款行为要么都成功,要么都失败

2、一致性:事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

例如:A和B两个人一共1000元,无论A,B两人互相转账多少次,A和B两个人总额都应该是1000元

3、隔离性:一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

例如:万达影院有《阿凡达2》电影票100张,允许所有人同时去淘票票上购票,当第100张电影票被A,B,C3人同时购买,如果A拿到第100张电影票,但是还在犹豫要不要付钱,则B,C必须等待A的决定,如果A决定付钱,B.C就无法抢到票,如果A超时不付钱,则这第100张电影票回归票池,从新分配。

4、持久性:持久性也称永久性,指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

例如:万达影院有《阿凡达2》电影票100张,100张电影票销售完毕,对于每个购买者来说,他的购买记录已经产生,即使退票,他之前的购买记录也不会消失。

二、事务的基本事务属性

1、传播行为:当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。Spring定义了七种传播行为。

传播行为含义
REQUIRED(默认)

当前如果有事务,Spring就会使用该事务;否则会开始一个新事务(增、删、改)

SUPPORTS

当前如果有事务,Spring就会使用该事务;否则不会开始一个新事务(查询)

MANDATORY表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常
REQUIRED_NEW

当前如果有事务,把当前事务挂起,新建事务

NOT_SUPPORTED

当前有事务,Spring也会在非事务环境下执行。如果当前有事务,则该事务挂起

NEVER

当前有事务,Spring也会在非事务环境下执行。如果当前有事务,则抛出异常

NESTED

当前有事务,则在嵌套事务中执行。如果没有,那么执行情况与REQUIRED一样

2、隔离级别:定义了一个事务可能受其他并发事务的影响程度。多个事务并发运行,经常会操作相同的数据来完成各自的任务,可能会出现脏读,不可重复读和幻读的问题。

脏读:在一个事务中读取到了另外一个事务修改的【未提交的数据】,而导致多次读取同一个数据返回的结果不一致 (必须要解决的)

不可重复读:在一个事务中读取到了另外一个事务修改的【已提交的数据】,而导致多次读取同一个数据返回的结果不一致

幻读: 一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了。再后来的查询中,第一个事务就会发现有些原来没有的记录

隔离级别有四种

隔离级别含义

DEFAULT

spring默认数据库的隔离级别

READ_UNCOMMITTED最低的隔离级别,允读取尚未提交的数据交互,可能会导致脏读、欢读或不可重复读
READ_COMMITTED允许读取并发事务已经提交的数据,可以阻止幻读,但是幻读或不可重复读仍有可能发生
REPEATABLE_READ对同一字段的多次读取结果都是一致的,除非数据是被本身事务所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
SERIALIZABLE最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复度以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现

隔离级别由低到高【读未提交】=>【读已提交】=>【可重复读】=>【序列化操作】

3、是否只读:如果一个方法内都是对数据库的select操作,那么可以设置方法事务为只读,数据库也会对该事务进行特定的优化。只读事务内不能有insert、update、delete的操作。

4、事务超时:事务可能设计对后端数据库的锁定,所以长时间的事务运行会不必要的占用数据库资源,设置事务超时时间可以及时释放资源

5、回滚规则:事务属性定义了哪些异常会导致事务回滚而哪些不会。默认情况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚

三、声明式事务管理的实现

Spring事务管理分为两种方式:编程式事务管理、声明式事务管理

以下以银行转账业务示例

编程式事务管理是通过编写代码实现的事务管理。可以根据需求规定事务从哪里开始,到哪里结束,拥有很高的灵活性。但是这种方式,会使业务代码与事务规则高度耦合,难以维护,因此我们很少使用这种方式对事务进行管理。

声明式事务管理: 采用声明的方式来处理事务,可以通过 2 种方式实现,分别是 XML和注解方式。Spring 在进行声明式事务管理时,底层使用了 AOP 。事务管理不侵入开发的组件。

以下为声明式事务管理的实现

1、创建实体类Account,生成get、set方法

2、在dao包下创建AccountDao接口


3、在dao包的impl子包下创建目标类AccountDaoImpl

4、创建service接口和实现类

AccountService接口

AccountServiceImpl实现类

5、在Spring配置类上启动事务管理

6、配置类JdbcConfig

7、测试

测试结果

发生异常,涉及转账业务的双方的金额均不变

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值