事务重点内容

发布时间:2024年01月24日

1. 含义

????????一组要么同时成功提交,要么同时失败回滚的sql语句,是数据库操作的一个执行单元。

2. 特性-ACID

? ? ? ? 1)原子性(Atomicity)

????????????????强调事务中的多个操作是一个整体:事务内所有操作是一个整体、最小执行单元,要么全部成功,要么全部失败。

? ? ? ? 2)一致性(Consistency)

????????????????强调事务中不会保存不一致的状态:从一个一致性状态转到另一个一致性状态,有一个失败,全部回滚。

? ? ? ? 3)隔离性(Isolation)

????????????????强调数据库事务中事务之间互相不可见:一个事务所做的修改在提交之前,其余的事务是不可见的,看不到事务的中间状态。

? ? ? ? 4)持久性(Durability)

????????????????强调数据库能永久保存数据库,一旦提交就不可撤销:事务提交,所有的修改都会永久保存到数据库。

3. 事务的并发问题

? ? ? ? 1)脏读

????????????????事务A读取了事务B尚未提交的数据。如果此时事务B由于失败导致数据回滚,那么事务A读取的数据就是脏数据。

????????????????

? ? ? ? 2)不可重复读(前后多次读取,数据内容不一致)

????????????????事务A读取了事务B提交的数据。事务A查询时,事务B查询并修改了同一条数据并提交,事务A再次读取到事务B修改后的数据,发现两次读取数据不一致,系统读取不到重复的数据,成为不可重复读。

????????????????

? ? ? ? 3)幻读(前后多次读取,数据总量不一致)

事务A读取了事务B新增或删除的数据,导致总数量不一致。事务A查询时,事务B新增了数据并提交,事务A再次查询时发现数据总量多了几条,就像产生了幻觉。

????????????????

? ? ? ? 4)小总结

????????????????脏读:读取了另一事务未提交的数据。

????????????????不可重复读:读取了另一事务提交了的更改数据,针对update。

????????????????幻读:读取了另一事务提交了的新增或删除数据,针对insert或delete。

4. 事务的隔离级别

????????数据库事务的隔离级别有4个,由低到高分别是Read uncommitted 、Read committed 、Repeatable read 、Serializable,级别越高,数据越安全,但性能越低。

????????分别可以解决脏读、不可重复读、幻读的问题。

????????

????????注意:Mysql中默认的隔离级别是:Repeatable read(可重复读)

5. 事务的传播行为

????????REQUIRED?:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。

????????SUPPORTS?:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。

????????MANDATORY?:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

????????REQUIRES_NEW?:创建一个新的事务,如果当前存在事务,则把当前事务挂起。

????????NOT_SUPPORTED?:以非事务方式运行,如果当前存在事务,则把当前事务挂起。

????????NEVER?:以非事务方式运行,如果当前存在事务,则抛出异常。

????????NESTED?:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 REQUIRED。

6.?事务的实现

????????@Transactional注解,既可以添加在方法上又可以添加在类上,当注解添加在类级别上,表示该类所有的公共方法都配置了相同的事务属性信息,

如果类级别和方法级别都配置了@Transactional,应用程序会优先以方法级别的事务属性来管理事务,换言之,方法级别的事务属性会覆盖类级别的事务属性。

????????建议:在业务层抛出异常,控制层统一处理。

7.?事务不生效

? ? ? ? 1)访问权限问题

????????????????java的访问权限主要有四种:private、default、protected、public,从左往右,权限依次变大;spring要求被代理的方法必须是public,其余权限spring不提供事务。

? ? ? ? 2)方法用final、static修饰

????????????????spring事务底层使用aop实现,jdk或cglib动态代理,如果使用final或static修饰了方法,在代理类里无法重写,无法实现事务。

? ? ? ? 3)方法内部调用

????????????????同一个类中有事务A的方法A调用了有事务B的方法B,相当于直接使用this调用方法B,所以事务B不生效

????????解决方法

? ? ? ? ? ? ? ? a. 新加一个service

????????????????????????

? ? ? ? ? ? ? ? b.?在该service注入自己

????????????????????????

? ? ? ? ? ? ? ? c.?通过AopContent类

????????????????????????

? ? ? ? 4)未被spring管理

使用spring的前提是,对象要被spring管理,如果service上不加@service注解,该类不由spring管理,事务自然不生效。

? ? ? ? 5)表不支持事务

? ? ? ? 6)多线程调用

? ? ? ? 7)未开启事务

8. 事务不回滚

? ? ? ? 1)错误的传播行为

????????????????@Transactional(propagation = Propagation.NEVER),这种传播行为不支持事务,有事务会抛异常

? ? ? ? 2)自己吞了异常-try...catch

????????????????主动捕捉了异常并处理,导致框架无法感知异常,无法回滚。

? ? ? ? 3)手动抛了别的异常

????????????????默认RuntimeException(运行时异常)和error(错误)回滚,Eexception(非运行时异常)就不回滚。

? ? ? ? 4)嵌套事务回滚(多了)

????????????????

????????????????实现只回归内部,不回滚外部,在内部手动捕捉异常-try...catch,并不继续往外抛。

????????????????????????

文章来源:https://blog.csdn.net/AngeliaXue/article/details/135777346
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。