【Spring面试】八、事务相关

这篇具有很好参考价值的文章主要介绍了【Spring面试】八、事务相关。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Q1、事务的四大特性是什么?

答案:

即ACID:

  • 原子性,Atomicity,即事务包含的所有操作要么同成功,要么同失败
  • 一致性,Cosistency,即事务必须使得数据库从一个一致性状态到两一个一致性状态。如用户A和用户B两者的钱加起来一共5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加来应该还得是5000,这就是事务的一致性
  • 隔离性,Isolation,多个事务并发时,之间要相互隔离,不能被其他事务干扰
  • 持久性,Durability,事务一旦提交,对数据库中数据的改变就是永久的,即使数据库故障也不会丢失提交事务的操作

Q2、Spring支持的事务管理类型有哪些?Spring事务实现方式有哪些?

答案: 支持的事务管理类型有两种

Spring支持两种类型的事务管理:

  • 编程式事务管理:灵活性高,但难维护
@Autowired
TransactionTemplate transactionTemplate ;

【Spring面试】八、事务相关,面试,spring,数据库,sql

  • 声明式事务管理:业务代码和事务管理分离,只需用注解和xml配置来管理事务。以下为基于注解@Transactional

【Spring面试】八、事务相关,面试,spring,数据库,sql

答案: 实现声明式事务的三种方式

  • 基于接口:Spring早期版本时用,更接近底层源码,有基于TransactionInterceptor的声明式事务,基于TransactionProxyFactoryBean的声明式事务
  • 基于<tx>和<aop>的xml声明式事务管理:和Spring AOP结合,利用切点表达式使得事务管理更加灵活
  • 基于@Transactional的全注解方式:在需要实施事务管理的方法或者类上加@Transactional注解,指定事务规则即可实现事务管理

Q3、说一下Spring的事务传播行为

答案:

两个事务方法之间的嵌套调用时,这个事务方法如何进行,即事务的传播特性。

@Transactional
public void trans(){
	sub();
	log();
	query();

}

@Transactional //SUPPORTS
public info query(){

}

@Transactional //REQUIRES_NEW
public void log(){

}

【Spring面试】八、事务相关,面试,spring,数据库,sql

以上面的query方法为例,其用SUPPORTS,即单独执行时不开启事务(就一个查询,当然不用开启),被有事务的外部方法调用时,则融入到这个外部方法的事务中,与他们同成功,同失败。(到大学了,和其余室友住一个屋子,还是你自己外面租一个新房子)

Q4、说一下Spring的事务隔离

答案:

事务隔离用来解决并发事务所产生的一些问题:

  • 脏读
  • 不可重复读
  • 幻影读

通过设置不同的隔离级别,可解决以上问题。

脏读:

【Spring面试】八、事务相关,面试,spring,数据库,sql

事务2只是改了余额,但并未提交,事务1就把这个没提交的值读走了,如果以后事务2最终回滚,就出问题了。即一个事务读取了另一个事务中没有提交的数据,会在本事务中产生数据不一致的问题。

@Transactional(isolation = isolation.READ_COMMITTED)

设置事务隔离策略为读已提交,只读别的并发事务已提交的修改

不可重复读:

【Spring面试】八、事务相关,面试,spring,数据库,sql
事务1先读后去处理其他事儿,然后期间事务2修改并commit,等事务1再读,则产生数据不一致的问题。

@Transactional(isolation = isolation.REPEATABLE_READ)

设置事务隔离策略为可重复读REPEATABLE_READ,确保事务1可以多次从一个字段中读到相同的值,即事务1执行期间禁止其他事务对这个字段进行更新(行锁)

幻影读:

不可重复读是针对一行数据,而幻影读则是针对整个表,比如两次读取,表中多出了一行数据:

【Spring面试】八、事务相关,面试,spring,数据库,sql
一个事务所在的方法中,多次进行整表数据读取,结果不一样,产生数据不一致问题。

@Transactional(isolation = isolation.SERIALIZABLE)

需要设置事务级别为串行化SERIALIZABLE,确保事务1可以多次从一个表中读到相同的行数,事务1执行期间,禁止其他事务对这个表进行增删改,但这样性能十分低下(表锁)

最后,当不设置事务隔离级别时,将默认使用底层所选数据库自身的默认事务隔离级别。

SELECT @@tx_isolation;

Q5、Spring事务的实现原理

以JavaConfig的方式为例,使用是:

//启动事务,这样可以使用@Transactional注解
@EnableTransactionManagement

答案:

没有Spring之前,单靠JDBC来操作是这样的:


try {
	//...
    //将事务提交机制改为手动提交
    conn.setAutoCommit(false);
    
    //业务逻辑
  
    //在这里事务结束,手动提交数据
    conn.commit();

}

Spring事务是把上面业务逻辑前后的事务开启与提交用AOP包了一下,即原理是:Spring事务底层是基于数据库事务和AOP机制。

  • 为使用了@Transactional注解的Bean创建一个动态代理对象(bean初始化后调用bean的后置处理器来创建动态代理)
  • 如果是事务方法(类上面、接口上面、方法上面、接口方法上面),则开启事务:
try{
	- 创建数据库连接
	- 修改数据库连接的autocommit属性为false,禁止此连接自动提交
	- 执行当前方法,方法中会执行数据库操作的业务SQL
	- 
}catch{
	- 若出现异常,且这个异常需要回滚,则回滚事务
}
  • 没有发生异常,则提交事务

Q6、Spring事务传播行为的实现原理是什么?

答案:

Spring的事务信息是存于ThreadLocal中的,所以一个线程永远只能有一个事务。对于被调用的事务方法,当:

  • 融入:当传播行为是融入外部事务,则拿到ThreadLocal中的Connection,共享一个数据库连接,来共同提交与回滚
  • 创建新事务:当传播行为是创建新的事务,则会把嵌套的新事务存入ThreadLocal,再将外部暂存起来,当嵌套事务提交或回滚后,再将暂存的外部事务信息恢复到ThreadLocal来提交或回滚

详细流程:

  • 外部:创建数据库连接Connection并存入ThreadLocal,修改数据库连接的autocommit属性为false
  • 外部:返回事务状态信息(TransactionInfo.newTransaction=true)
  • 外部:往下执行方法,中途发现内部调用了另一个事务方法
  • 内嵌:判断当前ThreadLoacl是否已有Connection,有即是内嵌事务,需要判断事务传播行为,到此分两种情况

情况一,当传播行为是融入

  • 不会创建connection,返回事务状态信息(TransactionInfo.newTransaction=false),即不是一个新事务
  • 内部被调用的事务方法开始执行相关SQL
  • 执行完后,判断TransactionInfo.newTransaction是否为true,此时是融入,这个值为false,不提交
  • 内部被调用的事务方法执行完成
  • 外部方法继续往下执行
  • 执行完后判断TransactionInfo.newTransaction是否为true,外部为true
  • 拿到ThreadLocal中的connection进行提交

情况二,当传播行为是创建新的事务

  • 把外层方法事务相关的事务信息(包括connection、隔离级别、是否只读…)暂存到TransactionInfo中,同时会把ThreadLocal中的事务信息置空
  • 创建新的connection,返回事务状态信息(TransactionInfo.newTransaction=true),即新事务,并放入ThreadLocal当中
  • 内部被调用的事务方法往下执行
  • 执行完后判断TransactionInfo.newTransaction是否为true⇒是⇒于是提交
  • 判断是否暂存了事务 ⇒ 是⇒ 再把上面暂存的外部方法的事务信息放回ThreadLocal中
  • 内部被调用的事务方法执行完成
  • 外部事务方法接着执行
  • 执行完后判断TransactionInfo.newTransaction是否为true,外部为true
  • 拿到ThreadLocal中的connection进行提交

Q7、Spring多线程事务,能否保证事务的一致性?

【Spring面试】八、事务相关,面试,spring,数据库,sql
问题分析:两个事务方法A和B,在两个线程中,对应的事务能否同时提交或回滚?

答案:

Spring不支持,因为Spring事务信息存于ThreadLocal中的Connection,一个线程永远只能有一个事务,所以无法实现两个事务的一致性。可以通过编程式事务自己控制或者分布式事务来解决(二阶段提交的方式)。

Q8、Spring事务失效的原因?

【Spring面试】八、事务相关,面试,spring,数据库,sql
Spring事务底层是基于数据库事务和AOP机制,因此,参考AOP失效,可以知道Spring事务失效的原因:

答案:

  • 方法的内部调用导致事务传播失效

【Spring面试】八、事务相关,面试,spring,数据库,sql

  • 方法是private会失效,解决: 改成public
  • 目标类没有配置为Bean也会失效 解决: 配置为Bean,交给Spring管理
  • 自己捕获了异常 解决: 不要捕获处理
  • 使用cglib动态代理,但是@Transactional声明在接口上面

后面几种本质上是使用不当导致的失效。文章来源地址https://www.toymoban.com/news/detail-732499.html

到了这里,关于【Spring面试】八、事务相关的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring面试】八、事务相关

    答案: 即ACID: 原子性 ,Atomicity,即事务包含的所有操作要么同成功,要么同失败 一致性 ,Cosistency,即事务必须使得数据库从一个一致性状态到两一个一致性状态。如用户A和用户B两者的钱加起来一共5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相

    2024年02月07日
    浏览(39)
  • 【建议收藏】数据库 SQL 入门——事务(内附演示)

    🙋‍♂️作者简介:生鱼同学,大数据科学与技术专业硕士在读👨‍🎓,曾获得华为杯数学建模国家二等奖🏆,MathorCup 数学建模竞赛国家二等奖🏅,亚太数学建模国家二等奖🏅。 ✍️研究方向:复杂网络科学 🏆兴趣方向:利用python进行数据分析与机器学习,数学建模竞

    2023年04月23日
    浏览(41)
  • 数据库相关面试题

    巩固基础,砥砺前行 。 只有不断重复,才能做到超越自己。 能坚持把简单的事情做到极致,也是不容易的。 mysql怎么优化 : MySQL的优化可以从以下几个方面入手: 数据库设计优化:合理设计表结构,选择合适的数据类型,规范化表结构,避免冗余数据等。 索引优化:为经常

    2024年02月12日
    浏览(41)
  • Sql Server 数据库事务与锁,同一事务更新又查询锁?期望大家来解惑

    我有一个People表,有三行数据: 如果我们没详细了解数据库事务执行加锁的过程中,会不会有这样一个疑问:如下的这段 SQL 开启了事务,并且在事务中进行了更新和查询操作。 我们知道sql server数据库的默认事务级别是READ COMMITTED(已提交的读取),我们再看一下已提交读事

    2024年02月01日
    浏览(56)
  • 数据库索引面试的相关问题

    查看索引的执行计划 索引失效的情况 1、索引列上做了计算,函数,类型转换等操作。索引失效是因为查询过程需要扫描整个索引并回表。代价高于直接全表扫描。 Like匹配使用了前缀匹配符“%abc” 字符串不加引号导致类型转换。 原因: 常见索引的优化的方法 1、前缀索引

    2024年02月22日
    浏览(44)
  • 数据库SQL查询相关练习

    1、显示所有职工的基本信息。 2、查询所有职工所属部门的部门号,不显示重复的部门号。 3、求出所有职工的人数。 4、列出最高工和最低工资。 5、列出职工的平均工资和总工资。 6、创建一个只有职工号、姓名和参加工作的新表,名为工作日期表。 8、列出所有姓刘的职工

    2024年01月25日
    浏览(49)
  • Sql Server 数据库事务与锁,同一事务更新又查询锁的变化,期望大家来解惑!

    我有一个People表,有三行数据: 如果我们没详细了解数据库事务执行加锁的过程中,会不会有这样一个疑问:如下的这段 SQL 开启了事务,并且在事务中进行了更新和查询操作。 我们知道sql server数据库的默认事务级别是READ COMMITTED(已提交的读取),我们再看一下已提交读事

    2024年02月01日
    浏览(73)
  • 【SQL Server】数据库开发指南(八)高级数据处理技术 MS-SQL 事务、异常和游标的深入研究

    本系列博文还在更新中,收录在专栏:#MS-SQL Server 专栏中。 本系列文章列表如下: 【SQL Server】 Linux 运维下对 SQL Server 进行安装、升级、回滚、卸载操作 【SQL Server】数据库开发指南(一)数据库设计的核心概念和基本步骤 【SQL Server】数据库开发指南(二)MSSQL数据库开发对

    2024年02月07日
    浏览(92)
  • MySQL相关的SQL语句、数据库、数据表、字段、类型

    1、 SQL 语句不区分大小写。 SQL语句 用途 描述 mysql -u root -p 连接 MySQL 在命令行窗口中输入 mysql -u root -p 命令,回车,然后输入 MySQL 密码(不要忘记了密码,找回麻烦),再回车就连接上 MySQL 了。最初都是使用 root 用户登录,工作中不能一直使用 root 用户登录。因为 root 权限太

    2024年02月13日
    浏览(95)
  • 【Spring】Spring的数据库开发

    1.1 Spring JdbcTemplate的解析     针对数据库的操作,Spring框架提供了 JdbcTemplate 类,该类是Spring框架数据抽象层的基础,其他更高层次的抽象类是构建于JdbcTemplate类之上的。可以说,JdbcTemplate类是Spring JDBC的核心类。JdbcTemplate类的继承关系十

    2023年04月23日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包