Spring中的事务
Spring中的事务
请类比MySQL中的事务,因为数据库操作不是原子性的,所以可能存在一些问题。例如我们代码的执行过程中,需要在表A中新增一条数据,在表B中也新增一条有关的数据。如果因为线路不稳定,表A新增成功了,表B新增失败了。最终结果自然是失败。但是数据库中会多出一条脏数据。因为表A已经新增成功了。所以我们就需要使用事务这一功能将操作强制原子化。
安装和配置
Spring-JDBC是Spring框架中对JDBC的增强工具类,通过Maven引入
1 | |
使用类来进行配置
1 | |
使用
很简单,在有关数据库操作的函数前加上@Transactional注释就能够声明为事务管理操作
1 | |
参数
使用该注释的参数模板是:
1 | |
事务隔离级别定义了多个事务并发执行时,彼此之间的可见性和影响程度。Spring支持标准SQL定义的4种隔离级别,用于解决并发事务可能引发的数据一致性问题。
1. 读未提交(READ_UNCOMMITTED)
- 问题:允许读取其他事务未提交的修改。
- 风险:脏读(Dirty Read)、不可重复读(Non-Repeatable Read)、幻读(Phantom Read)。
- 适用场景:对一致性要求极低,追求高并发性能。
2. 读已提交(READ_COMMITTED)
- 默认值:多数数据库(如Oracle)的默认隔离级别。
- 解决:避免脏读,但允许不可重复读和幻读。
- 适用场景:允许事务间看到已提交的数据变化(如统计报表)。
3. 可重复读(REPEATABLE_READ)
- 默认值:MySQL的默认隔离级别。
- 解决:避免脏读和不可重复读,但允许幻读。
- 机制:事务内多次读取同一数据的结果一致,但新增数据可能被其他事务插入(幻读)。
4. 串行化(SERIALIZABLE)
- 解决:强制事务串行执行,避免所有并发问题(脏读、不可重复读、幻读)。
- 代价:性能最低,仅适用于严格要求一致性且并发量小的场景。
传播行为:
传播行为定义了事务方法在调用其他事务方法时,事务如何传播。Spring提供了7种传播行为,以下是常见类型:
1. REQUIRED(默认)
- 规则:如果当前存在事务,则加入该事务;否则新建一个事务。
- 场景:大多数业务方法(如订单和库存操作需在同一个事务中)。
2. REQUIRES_NEW
- 规则:无论当前是否存在事务,都新建一个事务,并挂起当前事务(如果存在)。
- 场景:日志记录(即使主事务回滚,日志仍需提交)。
3. NESTED
- 规则:如果当前存在事务,则在嵌套事务(保存点)中执行;否则新建事务。
- 特点:嵌套事务回滚不影响外层事务,但外层事务回滚会导致嵌套事务回滚。
- 场景:复杂业务的分步操作(如订单创建成功后,部分子操作可独立回滚)。
4. SUPPORTS
- 规则:如果当前存在事务,则加入;否则以非事务方式运行。
- 场景:查询方法可适应有无事务的环境。
5. NOT_SUPPORTED
- 规则:以非事务方式执行,挂起当前事务(如果存在)。
- 场景:某些不需要事务的操作(如发送消息)。
6. MANDATORY
- 规则:强制当前必须存在事务,否则抛出异常。
- 场景:确保方法必须在事务上下文中调用。
7. NEVER
- 规则:强制当前不能存在事务,否则抛出异常。
- 场景:禁止事务的方法(如性能敏感的只读操作)。