什么是事务?
事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。
用专业的话来说,事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。也就是事务具有原子性,一个事务中的一系列的操作要么全部成功,要么一个都不做。
事务的特性?
事务有四个特性(ACID):
1.原子性(Atomicity)
事务是数据库的逻辑工作单位,事务中包括的诸操作要么全做,要么全不做。
2.一致性(Consistency)
事务必须使数据库从一个一致性状态变成另外一个一致性状态,事务开始和完成,数据必须保持一致。(数据不被破坏)
3.隔离性(Isolation)
一个事务的执行不能被其他事务干扰。
比如:当多个事务处于并发访问同一个数据库资源时,事务之间相互影响程度,不同的隔离级别决定了各个事务对数据资源访问的不同行为。
4.持续性/永久性(Durability)
一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。
SpringBoot事务配置?
1.依赖导入
在SpringBoot中使用事务,需要导入mybatis依赖:
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency>
导入依赖之后,SpringBoot会自动注入DataSourceTransactionManager ,无需其他配置就可使用@Transactional注解进行事务的使用。
2.具体示例
@Service public class UserServiceImpl implements UserService { @Resource private UserMapper userMapper; @Override @Transactional public void isertUser2(User user) throws Exception { // 插入用户信息 userMapper.insertUser(user); // 手动抛出异常 throw new SQLException("数据库异常"); } }
SpringBoot事务隔离级别?
事务隔离级别解决的是多个事务同时调⽤⼀个数据库的问题,如下图所示:
我们可以看 org.springframework.transaction.annotation.Isolation 枚举类中定义了五个表示隔离级别的值:
public enum Isolation { DEFAULT(-1), READ_UNCOMMITTED(1), READ_COMMITTED(2), REPEATABLE_READ(4), SERIALIZABLE(8); }
1.DEFAULT :默认值
Default是SpringBoot的隔离级别默认值,表示使用底层数据库的默认隔离级别。
大部分数据库为READ_COMMITTED,MySql默认隔离级别为REPEATABLE_READ。
2.Read uncommitted(读未提交)
一个事务可以读取另一个事务修改但还没有提交的数据。
3.Read committed(读提交)
一个事务只能读取另一个事务已经提交的数据。
比如:如果是一个读事务线程,则允许其他事务读写,如果是写事务将会禁止其他事务访问该行数据,该隔离级别避免了脏读,但是可能出现不可重复读。
事务A事先读取了数据,事务B紧接着更新了数据,并提交了事务,而事务A再次读取该数据时,数据已经发生了改变。
4.Repeatable read(可重复读取)
一个事务在整个过程中可以多次重复执行某个查询,并且每次返回的记录都相同。即使在多次查询之间有新增的数据满足该查询,这些新增的记录也会被忽略。
5.Serializable(可序化)
提供严格的事务隔离,它要求事务序列化执行,事务只能一个接着一个地执行,但不能并发执行。
指定方法可以通过使用 isolation 属性设置,例如:
@Transactional(isolation = Isolation.DEFAULT)
SpringBoot事务传播行为?
事务传播机制解决的是⼀个事务在多个节点:⽅法中传递的问题,如下图所示:
事务隔离级别是保证多个并发事务执⾏的可控性的:稳定性的,⽽事务传播机制是保证⼀个事务在多个调⽤⽅法间的可控性的:稳定性的。
我们可以看 org.springframework.transaction.annotation.Propagation 枚举类中定义了6个表示传播行为的枚举值:
public enum Propagation { REQUIRED(0), SUPPORTS(1), MANDATORY(2), REQUIRES_NEW(3), NOT_SUPPORTED(4), NEVER(5), NESTED(6); }
1.REQUIRED
默认的事务传播级别,它表示如果当前存在事务,则加⼊该事务,如果当前没有事务,则创建⼀个新的事务。
2.SUPPORTS
如果当前存在事务,则加⼊该事务,如果当前没有事务,则以⾮事务的⽅式继续运⾏。
3.MANDATORY
如果当前存在事务,则加入该事务,如果当前没有事务,则抛出异常。
4.REQUIRES_NEW
表示创建⼀个新的事务,如果当前存在事务,则把当前事务挂起,也就是说不管外部⽅法是否开启事务,Propagation.REQUIRES_NEW 修饰的内部⽅法会新开启⾃⼰的事务,且开启的事务相互独⽴互不⼲扰。
5.NOT_SUPPORTED
以⾮事务⽅式运⾏,如果当前存在事务,则把当前事务挂起。
6.Propagation.NESTED
如果当前存在事务,则创建⼀个事务作为当前事务的嵌套事务来运⾏;如 果当前没有事务,则该取值等价于 PROPAGATION_REQUIRED。
陈睿mikechen
10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获取更多技术干货!
后台回复【面试】即可获取《史上最全阿里Java面试题总结》,后台回复【架构】,即可获取《阿里架构师进阶专题全部合集》