深入理解 Spring 事务

深入理解 Spring 事务

  • 事务的特性
  • 事务的基本原理
  • 事务并发存在的问题
  • 事务的隔离级别
  • 事务的传播行为

事务的特性

事务是指多个操作命令认为是一体的,整体是不可分割的,操作要么全部成功,要么全部失败。四个原则:ACID。

1、原子性(Atomicity)
2、一致性(Consistency)
3、隔离性(Isolation)
4、持久性(Durability)

事务的基本原理

Mysql 在没有手动开启事务的情况下,默认一条执行命令就是一个事务。
对于 JDBC 操作数据库,想要用到事务,需要按照以下步骤进行:

1、加载数据库驱动:Class.forName(“com.mysql.jdbc.Driver”);
2、获取连接:Connection con = DriverManager.getConnection();
3、开启事务:con.setAutoCommit(false);
4、创建 statement 实例,专门用来执行 sql Statement statement = con.createStatement();
5、执行CRUD
6、提交事务/回滚事务:con.commit() / con.rollback();
7、关闭连接:conn.close();

使用 Spring 的事务管理功能后,开启事务、提交事务、回滚事务有 Spring 自动完成。
Spring 自动在 CRUD 之前和之后开启事务和关闭事务的原理如下:

1、配置开启事务注解驱动,在被需要事务管理的类或者方法上加上注解 @Transactional 。
2、Spring 启动的时候回解析生成相关的bean,为 @Transactional 类和方法生成代理类,然后在代理类中自动把相关的事务操作处理掉了。

事务并发存在的问题

脏读: 读取未提交的更新数据。关键词:未提交
不可重复读(读取了update并已提交的数据):在一个事务中读取一条数据,但是两次读取的数据不一样;读取了已提交的更新数据。关键词:update
幻读(读取了insert、delete并已提交的数据):在一个事务中查询两次,但是第二次比第一次多查询出一些数据;两次查询中间有别的事务插入数据了并事务已提交。关键词:insert、delete
丢失更新: 事务提交时,把其他事务已提交更新的数据覆盖了。

注意:不可重复读重点是修改,而幻读重点是新增或删除。

事务的隔离级别

Read Uncommitted(读未提交):可以读取未提交的更新数据;导致:脏读、不可重复读、幻读。
Read Committed(读已提交):可以读取已提交的更新数据;防止:脏读,导致:不可重复读、幻读。
Repetable Read(可重复读):对相同数据多次读取是一致的,除非数据被事务本身改变;防止脏读、不可重复读,导致:幻读。
Serilizable:锁定事务中涉及的数据,效率低下。防止:脏读、不可重复读、幻读。

MySQL默认采用Repetable Read隔离级别;Oracle默认采用Read Committed隔离级别。

事务的传播行为

1、PROPAGATION_REQUIRED(spring 默认)

支持当前事务;如果当前有事务,延用原来的事务,就如果当前没有事务,就新建一个事务。

2、PROPAGATION_REQUIRES_NEW

新建事务;如果当前有事务,就挂起当前事务。新建的事务和被挂起的事务没有任何关系,是两个独立的事务,外层事务失败回滚后,不能回滚内层事务执行的结果。

3、PROPAGATION_SUPPORTS

支持当前事务;如果当前没有事务,就以非事务方式执行。

4、PROPAGATION_NESTED

如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

另外三种事务传播属性基本用不到。

参考博客:
深入理解Spring事务的基本原理、传播属性、隔离级别
https://blog.csdn.net/mawenshu316143866/article/details/81281443

你可能感兴趣的:(Spring)