事务
事务特性
事务(Transaction)是由一系列对系统中数据进行访问与更新的操作所组成的一个程序 执行逻辑单元(Unit)。事务具有四个特征,分别是原子性(Atomicity )、一致性(Consistency )、隔离性(Isolation) 和持久性(Durability),简称为事务的ACID特性。
- 原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
- 一致性(Consistency):事务执行前后数据的完整性必须保持一致。比如在转账事务操作中,事务执行前后金额的总数应保持不变。
- 隔离性(Isolation):事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。
- 持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
事务并发执行带来的问题
1.丢失修改(丢失更新):两个事务T1和T2读入同一数据并修改,T2的提交结果破坏了T1提交的结果,导致T1的修改被丢失。
2.不可重复读:事务T1读取某一数据后,事务T2对其做了修改,当事务T1再次读该数据时,得到与前一次不同的值。
3.幻读:事务T1按一定条件从数据库中读取了某些数据记录后,事务T2删除了其中部分记录,当T1再次按相同条件读取数据时,发现某些记录消失了;或者说事务T2插入了部分新记录,当T1再次按相同条件读取数据时,发现多出来了部分数据。
注意:幻读和不可重复读的主要区别在于:
幻读针对的是查询结果为多个的场景,出现了数据的增加 or 减少
不可重复度读对的是某些特定的记录,这些记录的数据与之前不一致4.读“脏”数据:事务T1修改某一数据后,事务T2读取同一数据,然后T1由于某种原因操作被撤销(回滚),这时T1已修改过的数据恢复原值,T2读到的数据就与数据库中的真实数据不一致,这时T2读到的数据就为“脏”数据,即不正确的数据。
隔离级别
在标准SQL规范中,定义了4个事务隔离级别,不同的隔离级别对事务的处理不同,分别是:未授权读取,授权读取,可重复读取和串行化
传播性
springBoot中的事务
SpringBoot中的事务控制
- Spring提供了一个@EnableTransactionManagement注解在配置类上来开启声明式事务的支持(开启注解支持)。使用了@EnableTransactionManagement后,Spring容器会自动扫描注解@Transactional的方法和类。SpringBoot默认已开启,可不用显式注解。
- 要使用事务,我们只需要在需要事务的类或方法上使用@Transactional 注解即可,当注解在类上的时候意味着此类的所有public方法都是开启事务的。被注解的方法都成为一个事务整体,同一个事务内共享一个数据库连接,所有操作同时发生。如果在事务内部执行过程中发生了异常,则事务整体会自动进行回滚。
SpringBoot中的事务_阿阿阿安的博客-CSDN博客_springboot事务
spring中的事务
Spring事务传播属性(Propagation,7种传播行为):
- REQUIRED(默认属性)
如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务。
被设置成这个级别时,会为每一个被调用的方法创建一个逻辑事务域。如果前面的方法已经创建了事务,那么后面的方法支持当前的事务,如果当前没有事务会重新建立事务。
- REQUIRED(默认属性)
- MANDATORY
支持当前事务,如果当前没有事务,就抛出异常。
- MANDATORY
- NEVER
以非事务方式执行,如果当前存在事务,则抛出异常。
- NEVER
- NOT_SUPPORTED
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
- NOT_SUPPORTED
- REQUIRES_NEW
新建事务,如果当前存在事务,把当前事务挂起。
- REQUIRES_NEW
- SUPPORTS
支持当前事务,如果当前没有事务,就以非事务方式执行。
- SUPPORTS
- NESTED
支持当前事务,新增Savepoint点,与当前事务同步提交或回滚。
嵌套事务一个非常重要的概念就是内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。
- NESTED
2.隔离级别:(5种隔离级别)Spring对数据库来说隔离级别只有4种,不包括默认级别
- DEFAULT (默认)
这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。
- DEFAULT (默认)
- READ_UNCOMMITTED (读未提交)
这是事务最低的隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
- READ_UNCOMMITTED (读未提交)
- READ_COMMITTED (读已提交)
保证一个事务修改的数据提交后才能被另外一个事务读取,另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
- READ_COMMITTED (读已提交)
- REPEATABLE_READ (可重复读)
这种事务隔离级别可以防止脏读、不可重复读,但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了不可重复读
- REPEATABLE_READ (可重复读)
- SERIALIZABLE(串行化)
这是花费最高代价但是最可靠的事务隔离级别,事务被处理为顺序执行。除了防止脏读、不可重复读外,还避免了幻像读。
- SERIALIZABLE(串行化)
spring的事务与数据库的事务是否一样?
本质上其实是同一个概念,spring的事务是对数据库的事务的封装,最后本质的实现还是在数据库,假如数据库不支持事务的话,spring的事务是没有作用的.数据库的事务说简单就只有开启,回滚和关闭,spring对数据库事务的包装,原理就是拿一个数据连接,根据spring的事务配置,操作这个数据连接对数据库进行事务开启,回滚或关闭操作.但是spring除了实现这些,还配合spring的传播行为对事务进行了更广泛的管理.其实这里还有个重要的点,那就是事务中涉及的隔离级别,以及spring如何对数据库的隔离级别进行封装.事务与隔离级别放在一起理解会更好些