MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 数据库 / 正文

Spring事务注解@Transactional相关

2024-11-26 20:03 huorong 数据库 5 ℃ 0 评论

事务失效的场景

  • 访问权限不是public,spring要求被代理的方法权限必须是 public
  • 方法用 final 修饰 ,无法生成代理类
  • 方法内部调用
  • 修饰方法未被Spring管理
  • 多线程调用,因为Spring实现事务数据库连接存在threadLocal中,每个线程独享,如果多线程调用每个线程都有一个自己的数据库连接,就无法实现事务。
  • 表或者数据库不支持事务
  • 没有开启Spring事务 (SpringBoot默认开启、SpringMVC需要自己手动配置)
  • 事务传播特性设置的有问题 例如:Propagation.NEVER 这样就不会使用事务,并会抛出异常
  • 自己吞掉异常
  • 手动抛出了别的异常,Spring默认只会回滚,RunTimeException 和Error ,如果抛出了Exception 就不会回滚。
  • 自己设置指定异常回滚 ,但是没有抛出该异常。rollBackFor 参数指定
  • 嵌套事务,底层抛出导致上层也会滚,解决方案是手动cache

Spring事务的实现方式和原理

通过在某个方法上增加@Transactional注解,就可以开启事务,这个方法中所有的sql都会在一个事务中执行,统一成功或失败。

在一个方法上加了@Transactional注解后,Spring会基于这个类生成一个代理对象,会将这个代理对象作为bean,代理逻辑会先把事务的自动提交设置为false,然后再去执行原本的业务逻辑方法,如果执行业务逻辑方法没有出现异常,那么代理逻辑中就会将事务进行提交,如果执行业务逻辑方法出现了异常,那么则会将事务进行回滚。利用@Transactional注解中的rollbackFor属性进行配置对那些异常回滚,默认情况下会对RuntimeException和Error进行回滚。

Spring事务的隔离级别

spring事务隔离级别就是数据库的隔离级别外加一个默认级别

ISOLATION_DEFAULT(spring默认级别):使用后端数据库默认的隔离级别。

SOLATION_READ_UNCOMMITTED(未提交读):允许事务读取未被其他事务提交的变更数据,会出现脏读、不可重复读和幻读问题。

ISOLATION_READ_COMMITTED(提交读、不可重复读)(oracle默认级别)::只允许事务读取已经被其他事务提交的变更数据,可避免脏读,仍会出现不可重复读和幻读问题。

ISOLATION_REPEATABLE_READ(可重复读)(mysql默认级别):确保事务可以多次从一个字段中读取相同的值,在此事务持续期间,禁止其他事务对此字段的更新,可以避免脏读和不可重复读,仍会出现幻读问题。

ISOLATION_SERIALIZABLE(序列化):确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,可避免所有并发问题,但性能非常低。

数据库的配置隔离级别是Read Commited,而Spring配置的隔离级别是Repeatable Read,请问这时隔离级别是以哪一个为准?

以Spring配置的为准,如果spring设置的隔离级别数据库不支持,效果取决于数据库

Tags:oracle的事务

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言