返回顶部
首页 > 资讯 > 精选 >Spring接口方法加@Transactional失效如何解决
  • 263
分享到

Spring接口方法加@Transactional失效如何解决

2023-07-05 11:07:04 263人浏览 泡泡鱼
摘要

这篇文章主要介绍了spring接口方法加@Transactional失效如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring接口方法加@Transactional失效如何解决文章都会有所收获,下面

这篇文章主要介绍了spring接口方法加@Transactional失效如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring接口方法加@Transactional失效如何解决文章都会有所收获,下面我们一起来看看吧。

问题

今天项目测试一个方法的时候,发现日志报错

日志报错大致如下:Connection is read-only. Queries leading to data modification are not allowed

org.springframework.dao.TransientDataAccessResourceException:
### Error updating database.  Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed
### The error may involve com.o2o.app.repository.AccountOrdermybatisDao.updateOrder-Inline
### The error occurred while setting parameters
### SQL: UPDATE t_account_order SET ORDER_STATUS=?, STATUS_DESCRIPTION=?, IS_DELETE = ?           WHERE  TRADE_CODE = ? and TRADE_TYPE=?
### Cause: java.sql.SQLException: Connection is read-only. Queries leading to data modification are not allowed; SQL []; Connection is 
read-only. Queries leading to data modification are not allowed; nested exception is java.sql.SQLException: 
Connectionis read-only. Queries leading to data modification are not allowed

第一眼看上去,这不是Spring事务配置了只读事务属性,当执行sql写操作当然会失败了,为了更好解决这个bug,让我们先温习一下事务以及Spring在事务传播做了那些事?

  • 事务介绍

  • 事务(Transaction):指的是要做的事情,在计算机术语指的是访问并能更新数据库数据的一个程序执行单元

  • 由于我们日常开发,需要经常对关系型数据库打交道,这里简单介绍一下关系型数据库的事务四大属性

事务名称解释
原子性(Atomicity)事务是一个原子操作,原子操作简单理解指的是这个操作要么全部成功,要么全部失败
一致性(Consistency)事务无论成功与否,数据库必须保证所处的数据不应被破坏,举个例子:A给B无论成功或失败转账,那么A的钱+B的钱前后应该总和相等
隔离性(Isolation)同一份的数据可能有很多事务进行操作,因此要将各种事务隔离开,防止数据被损坏
持久性(Durability)事务如果一旦完成,结果都应不变,因为这样无论系统发送了什么错误,都能进行数据恢复
  • Spring事务核心类和接口

  • 如下图所示:在spring-tx包下有三个spring事务管理非常重要的接口 : PlatfORMTransactionManager,TransactionDefinition,TransactionStatus

Spring接口方法加@Transactional失效如何解决


spring并不实现各个数据库持久层的事务实现,而是提供对应的事务管理器,如下图所示:

Spring接口方法加@Transactional失效如何解决


我们首先查看PlatformTransactionManager接口的源代码:

Spring接口方法加@Transactional失效如何解决

TransactionStatus getTransaction(TransactionDefinition definition)

官方的解释是: Return a currently active transaction or create a new one, according to the specified propagation behavior

这句话的意思是根据指定的事务行为,返回当前的事务或者新建一个事务。

void commit(TransactionStatus status)

官方解释是:Commit the given transaction, with regard to its status. If the transaction has been marked rollback-only programmatically, perform a rollback.

这句话的意思是根据事务的状态提交事务,如果事务标记了rollback-only,请执行会滚。

void rollback(TransactionStatus status)

官方的解释是: Perform a rollback of the given transaction,即对事务进行回滚。

看到这里,我们需要明确三个接口中入参的TransactionDefinition是个什么东西呢?

让我们先大致查看一下TransactionDefinition接口的方法和成员变量,以下将会对此接口的方法做个简单的介绍,如下图所示:

Spring接口方法加@Transactional失效如何解决

  • 事务的传播行为

  • 当事务方法被调用时候,必须指定事务如何传播,下面是事务传播行为的介绍:

事务名称解释
PROPAGATION_REQUIRED支持当前的事务,如果当前事务不存在就新建一个事务
PROPAGATION_SUPPORTS支持当前事务,如果事务不存在,将以非事务方式运行
PROPAGATION_MANSATORY支持当前事务,如果事务不存在将抛异常
PROPAGATION_REQUIRES_NEW如果当前事务存在,将当前事务挂起并创建新的事务,如果当前事务不存在就新建一个事务
PROPAGATION_NOT_SUPPORTED不支持当前事务,以非事务的方式运行
PROPAGATION_NEVER不支持当前事务,如果当前事务存在就抛异常
PROPAGATION_NESTED如果当前事务存在,则执行一个内嵌的事务
  • 事务的隔离级别

  • 典型的事务隔离不同所造成问题如下:

脏读:脏读发送在A事务读取B事务已经改写但是还未提交的数据,若此时B事务回滚了,那么A事务获取就是脏数据

不可重复读:不可重复读发送在当A事务执行2次查询,每一次获取的数据结果都不相同,这是由于B事务在A事务2次查询期间进行了更新

幻读: 幻读发送在当A事务读取了几行数据,紧接着B事务进行输入的插入,在随后的查询中A事务就会读了原本不存在的记录

不可重复读特指修改的记录,而幻读指的是新增或删除的记录

  • 只读属性

  • 如果设置了只读事务,只读事务常常用于做查询使用,此时的增删改,将会报Connection is read-only. Queries leading to data modification are not allowed的异常。

  • 事务的超时

  • 一个正常和良好的程序,事务的行为时间并不会很长,较长的事务运行时间,会占用数据库资源,所以这里就设置超时时间,若指定时间内没有执行完事务,将会自动进行回滚

  • 事务的名称

  • 在一个事务行为中配置获取事务的名称,如我们常见的save,add,del 等等…

以上温习过Spring事务管理器和传播行为后,所以既然报错Connection is read-only. Queries leading to data modification are not allowed所以我们在接口方法的实现,加了以下的注解: @Transactional(propagation = Propagation.REQUIRED, readOnly = false),but!当我再次请求接口的时候,发现依然还是报同样的错误,百度一下,发现有相关问题博客的收集:Spring下默认事务机制中@Transactional 无效的原因

Method visibility and @Transactional When using proxies, you should apply the @Transactional annotation 
only to methods with public visibility. If you do annotate protected, private or package-visible methods with the
@Transactional annotation, no error is raised, but the annotated method does not exhibit the configured transactional settings. 
Consider the use of AspectJ (see below) if you need to annotate non-public methods.

大概意思是:如果你是使用默认的Spring aop代理方式将@Transaction注解应该用于公共可见即public的,如果对protected,或者private的方法加入@Transaction注解,则会无效。如果想在私有方法是使事务有效,可以用AspectJ进行实现。

but,我们的注解没有加在protected和private方法上,但是依然无效,why?

此次注解失效原因像下面简单的例子一样:在电商系统中,存在待支付的订单,假设有一个订单编号为201904191102的订单要进行支付,首先我需要刷新支付页面,就需要调用收银台接口,由于一直使用的Scala开发,所以下面的代码使用scala做演示:

    def refreshCashier(orderId: String): OrderInfo        def updateWallet(order:orderInfo):PayDto    override def refreshCashier(orderId: String): OrderInfo = {    // 伪代码,在这个方法里面调用 updateWallet方法  } @Transactional(propagation = Propagation.REQUIRED, readOnly = false)  override def updateWallet(order:orderInfo): PayDto = {   // 这里发送了异常   throw new AppException()  }

在上面的代码中,refreshCashier方法调用了updateWallet方法的时候,当updateWallet方法出错报异常,事务并没有回滚,这是因为Spring Aop动态代理会为每个class对象生成代理对象,只有在代理对象之间进行调用的时候,将会触发切面相关的逻辑处理。

所以要保证整个方法调用链的事务性,在refreshCashier方法加上@Transaction注解,此时才能保证,updateWallet方法出错时候,整个方法能进行事务的回滚。这样完美,问题解决了.

关于“Spring接口方法加@Transactional失效如何解决”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Spring接口方法加@Transactional失效如何解决”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网精选频道。

--结束END--

本文标题: Spring接口方法加@Transactional失效如何解决

本文链接: https://lsjlt.com/news/351510.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Spring接口方法加@Transactional失效如何解决
    这篇文章主要介绍了Spring接口方法加@Transactional失效如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring接口方法加@Transactional失效如何解决文章都会有所收获,下面...
    99+
    2023-07-05
  • 解读Spring接口方法加@Transactional失效的原因
    目录问题总结问题 今天项目测试一个方法的时候,发现日志报错 日志报错大致如下:Connection is read-only. Queries leading to data mod...
    99+
    2023-03-13
    Spring接口 @Transactional失效的原因 @Transactional失效
  • 如何解决@Transactional遇到try catch失效的问题
    这篇文章给大家分享的是有关如何解决@Transactional遇到try catch失效的问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。@Transactional遇到try catch失效Spri...
    99+
    2023-06-29
  • 事务注解@Transactional失效的场景及解决办法
    本篇内容主要讲解“事务注解@Transactional失效的场景及解决办法”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“事务注解@Transactional失效的场景及解决办法”吧!Transa...
    99+
    2023-06-15
  • spring注解事务失效如何解决
    在Spring中,如果注解式事务失效,可能有以下几个原因:1. 没有配置事务管理器:在Spring中,必须配置一个事务管理器来管理事...
    99+
    2023-09-28
    spring
  • mybatis接口绑定失效的解决
    目录mybatis接口绑定失效原因:小结一下mybatis接口绑定方法实现方法在XML中传递参数mybatis接口绑定失效 出现错误: org.apache.ibatis.bind...
    99+
    2024-04-02
  • thinkphp中c方法失效如何解决
    本篇内容主要讲解“thinkphp中c方法失效如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“thinkphp中c方法失效如何解决”吧!首先,我们需要了解一下什么是c方法。在ThinkPH...
    99+
    2023-07-05
  • php端口链接失败如何解决
    今天小编给大家分享一下php端口链接失败如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。php端口链接失败的解决办法:...
    99+
    2023-07-04
  • Runnable接口无start()方法如何解决
    Runnable接口无start()方法如何解决?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。自定义线程执行任务类public class ...
    99+
    2023-06-06
  • jdbc连接失效问题如何解决
    要解决JDBC连接失效问题,可以尝试以下几个方法: 检查数据库服务器是否正常运行:确保数据库服务器正常运行并且可以接收连接。可以...
    99+
    2023-10-24
    jdbc
  • Spring @Cacheable注解类内部调用失效的解决方法
    这期内容当中小编将会给大家带来有关Spring @Cacheable注解类内部调用失效的解决方法,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。@Cacheable注解类内部调用失效如果你只是想使...
    99+
    2023-06-22
  • Spring Boot 接口参数加密解密的实现方法
    目录1.开发加解密 starter2.打包发布2.1 安装到本地仓库2.2 发布到线上3.应用4.小结因为有小伙伴刚好问到这个问题,松哥就抽空撸一篇文章和大家聊聊这个话题。 加密解密...
    99+
    2024-04-02
  • Spring Boot JPA Repository之existsBy查询方法失效的解决
    引言: Spring Boot号称微服务的利器,在结合了Spring Data与JPA之后,更是如虎添翼,开发快速的不像话,本文将讲述一个关于JPA中一个诡异问题的诊断分析过程以及修...
    99+
    2024-04-02
  • 详解Spring中实现接口动态的解决方法
    前言本文主要给大家介绍的是关于Spring实现接口动态的相关内容,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍吧。关于这个问题是因为领导最近跟我提了一个需求,是有关于实现类Mybatis的@Select、@Insert注解的功...
    99+
    2023-05-31
    spring 动态接口
  • 如何解决Spring MVC接口漏洞百出
    这篇文章主要介绍“如何解决Spring MVC接口漏洞百出”,在日常操作中,相信很多人在如何解决Spring MVC接口漏洞百出问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何解决Spring MVC接口漏...
    99+
    2023-06-16
  • win11端口23连接失败如何解决
    如果您在Windows 11上尝试使用端口23进行连接,但失败了,可能存在以下几个原因和解决方法:1. 防火墙阻止了连接:Windo...
    99+
    2023-09-17
    win11
  • 如何解决spring boot项目使用@JsonFormat失效问题
    这篇文章给大家分享的是有关如何解决spring boot项目使用@JsonFormat失效问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。使用@JsonFormat失效在实体类定义时间格式原因:项目中配置了fa...
    99+
    2023-06-25
  • Spring事务管理下synchronized锁失效问题的解决方法
    目录一、我的思考二、图解出现的原因三、解决问题总结最近看到一个技术技术问题:synchronized锁问题? 开启10000个线程,每个线程给员工表的money字段【初始值是0】加1...
    99+
    2024-04-02
  • thinkphp eq失效如何解决
    这篇文章主要介绍了thinkphp eq失效如何解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇thinkphp eq失效如何解决文章都会有所收获,下面我们一起来看看吧。thinkphp eq失效的解决办法:...
    99+
    2023-07-04
  • setcookie php失效如何解决
    这篇文章主要介绍“setcookie php失效如何解决”,在日常操作中,相信很多人在setcookie php失效如何解决问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”setcookie php失效如何解决...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作