Spring事务的ACID
事务的ACID分别指的是原子性、一致性、隔离性、持久性,spring事务中定义了如下属性用于实现事务的ACID特性
- 事务名称
- 隔离级别(4种)
- ISOLATION_READ_UNCOMMITTED:运行B事务看到A事务未提交的数据,会造成脏读、不可重复读和幻像读。
- ISOLATION_READ_COMMITTED:事务B只能看到其他事务已提交后的数据状态,解决的了脏读,会造成不可重复读+幻读
- ISOLATION_REPEATABLE_READ:该级别解决了脏读、不可重复读,但是存在幻读,其解决不可重复读的原理如下:
- select … from :该Repeatable-read的算法处理中,在同一个事物内多次读取,则取第一次读取时建立的快照版本
- ISOLATION_SERIALIZABLE:这是事务的最高隔离级别,底层实现是通过对每一行读取的数据加共享锁(Lock in Share Mode)实现,容易造成事务超时与锁竞争
- 超时时间
- 是否只读(ReadOnly)
- 传播机制(7种)
- REQUIRED:存在事务则加入,不存在则新建
- SUPPORT:存在事务则加入,不存在则以非事务执行
- MANDATIORY:存在事务则加入,不存在则抛出异常
- REQUIRES_NEW:存在事务则挂起,新建一个事务执行处理
- NOT_SUPPORTED:存在事务则挂起,以非事务执行,
- NEVER:存在事务则抛出异常
- NESTED:存在则嵌套,不存在则创建新的事务
- 回滚机制
Spring事务的应用
在默认的数据库事务中,每执行一次数据库操作都封装在一个事务中,若操作成功则提交事务,若失败则回滚,类似于使用jdbc编程中的获取到Connection后,执行connection.setAutoCommit(false);在执行完毕后进行connection.commit();
Springboot中开启的方式为在启动类中引入注解@EnableTransactionManagement,用于配置申明式事务
@SpringBootApplication
@EnableTransactionManagement //开启spring事务
public class DmUtilsApplication {
public static void main(String[] args) {
SpringApplication.run(DmUtilsApplication.class,args);
}
}
- 编程式事务
编程式事务管理使用底层源码实现更细粒度的事务控制,spring推荐transactionTemplate来实现,代码如下
//事务管理需求,插入用户表后需要同时更新账户余额表,若俩者有一个失败,则事务回滚
@Service
public class UpdateService implements UpdateDao {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private TransactionTemplate transactionTemplate; //先注入事务管理类
/**
* 创建用户并创建账户余额(手动事务,不带结果)
*
* @param name
* @param balance
* @return
*/
@Override
public void addUserBalanceAndUserWithinTT(String name, BigDecimal balance) {
//实现一个没有返回值的事务回调
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
try {
log.info("[addUserBalanceAndUser] begin!!!");
//1.新增用户
userService.addUser(name);
//2.新增用户余额
UserBalance userBalance = new UserBalance();
userBalance.setName(name);
userBalance.setBalance(new BigDecimal(1000));
userBalanceRepository.insert(userBalance);
log.info("[addUserBalanceAndUser] end!!!");
//注意:这里catch住异常后,设置setRollbackOnly,否则事务不会滚。当然如果不需要自行处理异常,就不要catch了
} catch (Exception e) {
// 异常回滚
status.setRollbackOnly();
log.error("异常回滚!,e={}",e);
}
}
});
}
}
----------------------------------------
- 申明式事务
/**
* 创建用户并创建账户余额
*
* @param name
* @param balance
* @return
*/
@Transactional(propagation= Propagation.REQUIRED, rollbackFor = Exception.class)
@Override
public void addUserBalanceAndUser(String name, BigDecimal balance) {
log.info("[addUserBalanceAndUser] begin!!!");
//1.新增用户
userService.addUser(name);
//2.新增用户余额
UserBalance userBalance = new UserBalance();
userBalance.setName(name);
userBalance.setBalance(new BigDecimal(1000));
this.addUserBalance(userBalance);
log.info("[addUserBalanceAndUser] end!!!");
}
本文主要介绍了Spring事务的ACID特性,包括事务的四个隔离级别及其防止的问题,如脏读、不可重复读和幻读。此外,还讨论了事务的超时时间、只读属性以及传播机制的七种类型。接着,提到了Spring事务的回滚机制,并阐述了Springboot中启用事务管理的方法。最后,简要提及了编程式事务管理,特别是如何使用transactionTemplate进行细粒度的事务控制。
947

被折叠的 条评论
为什么被折叠?



