说起事务,就不得不谈谈事务的四大特性:
事务是一系列的操作,由一条或多条sql语句组成。是不可分割的整体,是最小的操作单位。
事务的特性:ACID
原子性(Atomicity):
最小的执行单元。(要么全成功,有一条失败则回滚到最初状态)
一致性(Consistency):
事务完成时所用的数据从一种一致性状态变为另一种一致性状态,所用的变更必须是在事务中进行修改,确保数据的完整性。
隔离性(Isolation):
一个事务中的操作不能受其它事务的影响,多事务对数据的操作相互隔离,一个事务不能看到另一个事务 正在修改的数据。
持久性(Durability):
事务执行完毕后,对数据的修改应持久保存在磁盘中。
数据库的隔离级别
隔离级别 | 隔离级别的值 | 脏读 | 不可重复读 | 幻读 |
读未提交 Read-Uncommitted | 0 | 是 | 是 | 是 |
读已提交 (read-committed) | 1 | 否 | 是 | 否 |
可重复读 (repeatable-read) | 2 | 否 | 否 | 是 |
可串行化 (serializable) | 3 | 否 | 否 | 否 |
1. 脏读:一个事务读到另一个事务未提交的内容【读取未提交内容】
在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。
2. 不可重复读:一个事务读到另一个事务已提交的内容(insert)【读取提交内容】
是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
3. 幻读(虚读):一个事务读到另一个事务已提交的内容,是事务非独立执行时发生的一种现象。
幻读 (Phantom Read),简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。
- read uncommittd,读未提交。存在3个问题(脏读、不可重复读、幻读)。
- read committed,读已提交。解决:脏读。存在2个问题。
- repeatable read ,可重复读。解决:脏读、不可重复读。存在1个问题。
- serializable,串行化。单事务。没有问题。 这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。
小结:
1. 隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。像serializable,是用锁表的方式使得其他线程只能在锁外等候,用何种隔离级别应根据实际情况。
2. 大多数的数据库默认隔离级别为 Read Commited,比如 SqlServer、Oracle。
3. 少数数据库默认隔离级别为:Repeatable Read 比如: MySQL、 InnoDB。
Spring中的隔离级别
常量 | 解释 |
ISOLATION_DEFAULT | 这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与 JDBC 的隔离级别相对应。 |
ISOLATION_READ_UNCOMMITTED | 这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。 |
ISOLATION_READ_COMMITTED | 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。 |
ISOLATION_REPEATABLE_READ | 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。 |
ISOLATION_SERIALIZABLE | 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。 |
1. ISOLATION_DEFAULT:用底层数据库的默认隔离级别,数据库管理员设置什么就是什么
2.ISOLATION_READ_UNCOMMITTED(未提交读):最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)
3. ISOLATION_READ_COMMITTED(提交读):一个事务提交后才能被其他事务读取到(该隔离级别禁止其他事务读取到未提交事务的数据、所以还是会造成幻读、不可重复读)、sql server默认级别
4. ISOLATION_REPEATABLE_READ(可重复读):可重复读,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(该隔离基本可防止脏读,不可重复读(重点在修改),但会出现幻读(重点在增加与删除))(MySql默认级别,更改可通过set transaction isolation level 级别)
5. ISOLATION_SERIALIZABLE(序列化):代价最高最可靠的隔离级别(该隔离级别能防止脏读、不可重复读、幻读)
1. 丢失更新:两个事务同时更新一行数据,最后一个事务的更新会覆盖掉第一个事务的更新,从而导致第一个事务更新的数据丢失,这是由于没有加锁造成的;
2. 幻读:同样的事务操作过程中,不同时间段多次(不同事务)读取同一数据,读取到的内容不一致(一般是行数变多或变少)。
3. 脏读:一个事务读取到另外一个未提及事务的内容,即为脏读。
4. 不可重复读:同一事务中,多次读取内容不一致(一般行数不变,而内容变了)。
幻读与不可重复读的区别:
幻读的重点在于插入与删除,即第二次查询会发现比第一次查询数据变少或者变多了,以至于给人一种幻象一样,而不可重复读重点在于修改,即第二次查询会发现查询结果比第一次查询结果不一致,即第一次结果已经不可重现了。
数据库隔离级别越高,执行代价越高,并发执行能力越差,因此在实际项目开发使用时要综合考虑,为了考虑并发性能一般使用提交读隔离级别,它能避免丢失更新和脏读,尽管不可重复读和幻读不能避免,但可以在可能出现的场合使用悲观锁或乐观锁来解决这些问题。
Spring事务管理
1. spring事务依赖的jar包
jar包中的三个顶级接口
PlatformTransactionManager | 平台事务管理器,spring要管理事务,必须使用事务管理器,进行事务配置时,必须配置事务管理器 |
TransactionDefinition | 事务详情(事务定义、事务属性),spring用于确定事务具体详情,例如:隔离级别、是否只读、超时时间 等。进行事务配置时,必须配置详情。spring将配置项封装到该对象实例 |
TransactionStatus | 事务状态,spring用于记录当前事务运行状态。例如:是否有保存点,事务是否完成。spring底层根据状态进行相应操作。 |
1.1 PlatformTransactionManager 事务管理器
常见的事务管理器:
1.2 TransactionDefinition 事务详情
1.3 TransactionStatus 由spring底层根据状态进行相应的操作
2. 当我们调用一个基于Spring的service层的方法时,它将运行于spring管理的事务当中,spring通过事务的传播行为控制当前事务如何传播到被嵌套调用的目标服务接口方法中。
事务的传播行为类型(7种)
传播行为就是定义在存在多个事务同时存在的时候,spring应该如何处理这些事务的行为。
即在两个业务之间如何共享事务。
PROPAGATION_REQUIRED required , 必须 【默认值】 | 支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将创建一个新的事务。 |
PROPAGATION_SUPPORTS supports ,支持 | 支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将以非事务执行。 |
PROPAGATION_MANDATORY mandatory ,强制 | 支持当前事务,A如果有事务,B将使用该事务。 如果A没有事务,B将抛异常。 |
PROPAGATION_REQUIRES_NEW requires_new ,必须新的 | 如果A有事务,将A的事务挂起,B创建一个新的事务 如果A没有事务,B创建一个新的事务 |
PROPAGATION_NOT_SUPPORTED not_supported ,不支持 | 如果A有事务,将A的事务挂起,B将以非事务执行 如果A没有事务,B将以非事务执行 |
PROPAGATION_NEVER never,从不 | 如果A有事务,B将抛异常 如果A没有事务,B将以非事务执行 |
PROPAGATION_NESTED nested ,嵌套 | A和B底层采用保存点机制,形成嵌套事务。 |
spring手动实现事务
手动实现事务配置:
tx:atributes 配置事务的属性,以方法为单位进行配置。可以通过通配符的命名方法进行批量配置。
使用注解完成事务匹配置:
注解可以加在方法上或类上,根据需求决定。方法上的注解会覆盖类上面的注解
注解方式实现spring的事务管理的简单介绍
1. 配置文件开启注解驱动,在相关类和方法上通过注解@Transactional标识。
2. spring在启动的时候会去解析生成相关的bean,这时候会查看拥有相关注解的类和方法,并且为这些类和方法生成代理,并根据@Transactional的相关参数进行相关配置注入,这样就在代理中为我们把相关的事务处理掉了(开启正常提交事务,异常回滚事务)。
欢迎留言。。。
关于spring中的事务和数据库事务的理解可以参考博客:https://blog.csdn.net/duan196_118/article/details/104814284