【Spring 持久层,Java大厂面试攻略

进行动态代理底层实现的切换,默认 `false` 是 JDK,`true` 是 Cglib。

<tx:annotation-driven transaction-manager="dataSourceTransactionManager" proxy-target-class="true"/> 

Spring 中的事务属性(Transaction Attribute)

=======================================================================================================

什么是事务属性

属性:描述物体特征的一系列值(性别、身高、体重)

事务属性:描述事务特征的一系列值

  1. 隔离属性

  2. 传播属性

  3. 只读属性

  4. 超时属性

  5. 异常属性

如何添加事务属性?


@Transactional(isolation=, propagation=, readOnly=,timeout=,rollbackFor,noRollbackFor=,) 


隔离属性(ISOLATION)


概念:描述了事务解决并发问题的特征

  1. 什么是并发?

    多个事务(用户)在同一时间,访问操作了相同的数据。

    同一时间:0.000 几秒左右

  2. 并发会产生那些问题?

    • 脏读

    • 不可重复读

    • 幻影读

  3. 并发问题如何解决?

    通过隔离属性解决,隔离属性中设置不同过的值,解决并发处理的过程中的问题。


事务并发产生的问题:

  • 脏读

    一个事务,读取了另一个事务中没有提交的数据,会在本事务中产生数据不一样的现象

    解决方案:@Transaction(isolation=Isolation.READ_COMMITTED)

  • 不可重复读

    一个事务中,多次读取相同的数据,但是读取结果不一样,会在本事务中产生数据不一样的现象

    注意:1.不是脏读 2.在一个事务中

    解决方案:@Transaction(isolation=Isolation.REPEATABLE_READ)

    本质:一把行锁(对数据库表的某一行加锁)

  • 幻影读

    一个事务中,多次对整表进行查询统计,但是结果不一样,会在本事务中产生数据不一致的问题

    解决方案:@Transaction(isolation=Isolation.SERIALIZABLE)

    本质:表锁(对数据库某个表加锁)


安全与效率对比:

  • 并发安全:SERIALIZABLE > READ_ONLY > READ_COMMITTED

  • 运行效率:READ_COMMITTED > READ_ONLY > SERIALIZABLE


数据库对隔离属性的支持:

| 隔离属性的值 | MySQL | Oracle |

| — | — | — |

| ISOLATION_READ_COMMITTED | 支持 | 支持 |

| ISOLATION_REPEATABLE_READ | 支持 | 不支持 |

| ISOLATION_SERIALIZABLE | 支持 | 支持hi |

  • Oracle 不支持 REPEATABLE_READ,那该如何解决不可重复读?

    采用 多版本比对 的方式解决不可重复读问题。


默认的隔离属性

  • Spring 会指定为 ISOLATION_DEFAULT,调用不同数据库所设置的默认隔离属性

    MySQL:REPEATABLE_READ

    Oracle:READ_COMMITTED

  • 查看数据库的默认隔离属性:

    MySQL:SELECT @@tx_isolation;

    Oracle:较麻烦,建议百度。


隔离属性在实验中的建议

  • 推荐使用 Spring 默认指定的 ISOLATION_DEFAULT

  • 未来的实战中,遇到并发访问的情况,很少见

  • 如果真的遇到并发问题,解决方案:乐观锁

    Hibernate(JPA):version

    MyBatis:通过拦截器自定义开发

传播属性(PROPAGATION)


概念:描述了事务解决 嵌套 问题 的特征。

事务的嵌套:指的是一个大的事务中,包含了若干个小的事务。

事务嵌套产生的问题: 大事务中融入了很多小的事务,他们彼此影响,最终就导致外部大的事务丧失了事务的原子性。

传播属性的值及其用法:

| 传播属性的值 | 外部不存在事务 | 外部存在事务 | 用法 | 备注 |

| — | — | — | — | — |

| REQUIRED | 开启新的事务 | 融合到外部事务中 | @Transactional(propagation = Propagation.REQUIRED) | 增、删、改方法 |

| SUPPORTS | 不开启事务 | 融合到外部事务中 | @Transactional(propagation = Propagation.SUPPORTS) | 查询方法 |

| REQUIRES_NEW | 开启新的事务 | 挂起外部事务,创建新的事务 | @Transactional(propagation = Propagation.REQUIRES_NEW) | 日志记录方法中 |

| NOT_SUPPORTED | 不开启事务 | 挂起外部事务 | @Transactional(propagation = Propagation.NOT_SUPPORTED) | 极其不常用 |

| NEVER | 不开启事务 | 抛出异常 | @Transactional(propagation = Propagation.NEVER) | 极其不常用 |

| MANDATORY | 抛出异常 | 融合到外部事物中 | @Transactional(propagation = Propagation.MANDATORY) | 极其不常用 |

Spring 中传播属性的默认值是:REQUIRED

推荐传播属性的使用方式:

  • 增删改 方法:使用默认值 REQUIRED

  • 查询 方法:显示指定传播属性的值为 SUPPORTS

只读属性(readOnly)


针对于 只进行查询操作的业务方法,可以加入只读属性,提高运行效率。

默认值:false


@Transactional(readOnly = true) 

超时属性(timeout)


指定了事务等待的最长时间。

  1. 为什么事务会进行等待?

    当前事务访问数据时,有可能访问的数据被别的事务进行加锁的处理,那么此时本事务就必须进行等待。

  2. 等待时间,单位是

  3. 如何使用:@Transactional(timeout = 2)

  4. 超时属性的默认值:-1

    -1 表示超时属性由对应的数据库来指定(一般不会主动指定,-1 即可)

异常属性


Spring 事务处理过程中:

  • 默认对于 RuntimeException 及其子类,采用 回滚 的策略。

  • 默认对于 Exception 及其子类,采用 提交 的策略。

使用方法:


@Transactional(rollbackFor = java.lang.Exception.class, xxx, xxx)



@Transactional(noRollbackFor = java.lang.RuntimeException, xxx, xxx) 

建议:实战中使用 RuntimeException 及其子类,使用事务异常属性的默认值。

事务属性常见配置总结


  1. 隔离属性 默认值

  2. 传播属性 Required(默认值)增删改、Supports 查询操作

  3. 只读属性 readOnly=false 增删改,true 查询操作

  4. 超时属性 默认值 -1

  5. 异常属性 默认值

增删改操作:@Transactional

查询操作:@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)

基于标签的事务配置方式

==============================================================================

基于注解 @Transaction 的事务配置回顾:


<bean id="userService" class="com.yusael.service.UserServiceImpl">

	<property name="userDAO" ref="userDAO"/>

</bean>




# **感受:**

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

**也祝愿各位同学,都能找到自己心动的offer。**

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档,**[需要的朋友可以【点赞+关注】戳这里即可免费获取](https://gitee.com/vip204888/java-p7)**

O"/>

</bean>




# **感受:**

其实我投简历的时候,都不太敢投递阿里。因为在阿里一面前已经过了字节的三次面试,投阿里的简历一直没被捞,所以以为简历就挂了。

特别感谢一面的面试官捞了我,给了我机会,同时也认可我的努力和态度。对比我的面经和其他大佬的面经,自己真的是运气好。别人8成实力,我可能8成运气。所以对我而言,我要继续加倍努力,弥补自己技术上的不足,以及与科班大佬们基础上的差距。希望自己能继续保持学习的热情,继续努力走下去。

**也祝愿各位同学,都能找到自己心动的offer。**

分享我在这次面试前所做的准备(刷题复习资料以及一些大佬们的学习笔记和学习路线),都已经整理成了电子文档,**[需要的朋友可以【点赞+关注】戳这里即可免费获取](https://gitee.com/vip204888/java-p7)**

![拿到字节跳动offer后,简历被阿里捞了起来,二面迎来了P9"盘问"](https://img-blog.csdnimg.cn/img_convert/d3472d0025d7359fd4c9bb63943e7ba0.png)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值