vlambda博客
学习文章列表

大厂问你spring事务的面试题,你能多少?

面试真题:

1、什么是事务?
2、事物的特性有哪些
3、事务的隔离级别有哪些?不同的隔离级别分别会存在什么问题?
4、事物的传播机制有哪些?在做项目的时候,一般用的是哪个隔离级别?这些隔离级别分别用在什么场景?
5、@Transaction的属性你设置过哪些?分别是用来干什么的?6、spring事务的同步器用过吗?

1、什么是事务

事务:事务是一组执行单元,要么全部执行,要么全部不执行

2、事务的特性

原子性:事务的操作要么全部执行,要么全部回滚
一致性:事务执行前后,数据保持一致
隔离性:各个事务之间,独立执行,互不干扰。
持久性:一个事务被提交之后,在数据库中永久保存

3、spring事务管理接口介绍

PlatformTransactionManger:指定事务平台管理器,指定的是持久化框架提供的事务管理器。spring不直接管理事务,所以会将事务委托给持久化框架的提供的事务管理器
TransactionDefinition:事务定义信息(可以指定事务的隔离级别、传播行为、超时、只读、回滚规则)
TransactionStatus:事务的运行状态。(提供了是否创建了新事物、是否设置了回滚只读的、事务是否完成等方法)

4、事务的隔离级别

读未提交:一个事务把另一个事务没有提交的事务读取了
读已提交:一个事务只能读取另一个事务提交的数据
可重读:一个事务可以对一个数据进行多次读取
串行化:事务一个一个的串行提交

5、不同隔离级别所带来的问题

脏读:一个事务把另一个事务没有提交的事务读取了。这是读未提交隔离级别存在的问题。读已提交以上的隔离级别可以避免这个问题。

不可重读:一个事务执行多次读取一个数据的操作返回不同的数据。产生原因是一个事务在执行读取操作的时候,其它事务会对数据进行修改的操作,可重读以上的隔离级别可以避免这个问题。

幻读:一个事务在读取多行数据的时候,可能会多出或者删除数据的现象。产生原因是因为其它事务可能会同时对那几行数据执行添加或者删除的操作,串行化可以避免这个问题

6、spring的传播行为

场景说明:现在有两个服务serviceA和serviceB,serviceA的methodA调用了serviceB的methodB

propagation.required:必须要有事务,默认传播行为。如果方法A有事务,方法B则加入方法A的事务,两个方法合并为一个事务。如果方法A没有事务,则新建一个事务
propagation.require_new:新建一个事务。如果方法A有事务,则把方法A的事务挂起,方法B新建一个事务,不受方法A事务的影响,独立提交。即使方法A报异常,也不会影响方法B的事务提交
propagation.nested:嵌套事务。如果方法A有事务,则方法B将成为方法A的子事务。如果方法A没有事务,则创建新事物。方法B执行完之后,并不马上提交,而是要等到方法A执行完才一起提交事务。方法B的事务如果报异常,方法A的事务可以捕获方法B的事务的异常,可以不进行回滚。如果方法A报异常,则一定会回滚。
propagation.supports:支持事务。如果方法A有事务,则加入事务。如果方法A没有事务,则以非事务的方式执行
propagation.not_supported:不支持事务。如果方法A有事务,则将事务挂起。如果没有事务,则以非事务的方式执行
propagation.mandatory:强制。如果方法A有事务,则加入当前的事务。如果没有事务,则抛出异常
propagation.never:强制没有事务。如果方法A有事务,则抛出异常。如果没有事务,则以非事务的方式执行

7、@Transactional注解的属性介绍

transactionManager:指定事务管理器 propagation:指定事务的传播行为,默认required
isolation:指定事务的隔离级别,默认和数据库的隔离级别保持一直
timeout:该事务的超时时间,默认值为-1,代表事务使用的是事务系统默认的超时时间
readOnly:默认值为false,true表示该事务只读 rollbackfor:指定0个或者多个异常,捕获到这些异常必须回滚
noRollbackFor:指定0个或者多个异常,遇到这些异常不进行回滚

注意事项:
1)如果不设置任何属性,那只有遇到了RuntionException和Error时才会回滚
2)如果设置为了只读之后,事务只能进行读取操作,如果试图进行修改数据的操作则会抛出异常

8、spring事务同步器的使用

事务同步器是spring用来监听事务的状态变化的,它主要提供了一下几个方法:
suspend:在事务被挂起的时候调用
resume:在事务恢复的时候调用 beforeCommit和beforeCompletion是在事务提交之前被调用,发生在事务之中
afterCommitafterCompletion是在事务提交之后被调用,发生在事务之外

写在最后

作为一个还算年轻的程序员来说,写博客也算是一种技术自我巩固的一个过程,我也希望和大家一起成长。
如果博客有什么不正确的地方,欢迎评论指正。如果觉得写得不错,欢迎点赞收藏转发。