返回顶部
首页 > 资讯 > 后端开发 > Python >聊聊spring @Transactional 事务无法使用的可能原因
  • 533
分享到

聊聊spring @Transactional 事务无法使用的可能原因

2024-04-02 19:04:59 533人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

spring transaction 建议 Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解, 而不要使用在类所要实现的任何接口上。你当然

spring transaction

建议

Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解,

而不要使用在类所要实现的任何接口上。你当然可以在接口上使用 @Transactional 注解,

但是这将只能当你设置了基于接口的代理时它才生效。

因为注解是不能继承的,

这就意味着如果你正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,

而且对象也将不会被事务代理所包装(将被确认为严重的)。

因此请接受Spring团队的建议并且在具体的类上使用 @Transactional 注解。

事务无法使用的可能原因

导入spring的事务注解

应该是


org.springframework.transaction.annotation.Transactional

而不是


javax.transaction.Transactional

是否开启了对注解的解析:

xml 文件配置


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

SpringBoot

注解开启自动扫描


@EnableTransactionManagement

spring是否扫描到你使用注解事务的这个类所在的包

配置xml


<context:component-scan base-package="com.xxx.xxx" ></context:component-scan>

springboot 开启事务


@EnableTransactionManagement

数据库引擎要支持事务

如果是Mysql,注意表要使用支持事务的引擎,比如InnoDB,如果是myisam,事务是不起作用的

springboot的配置


spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.mysql5InnoDBDialect

检查方法是不是public的

@Transactional 仅仅在 public 方法,才能进行事务管理。

photo_1

这是因为在使用 Spring aop 代理时,

Spring 在调用在图中的 TransactionInterceptor 在目标方法执行前后进行拦截之前(图中是cglib代理)

DynamicAdvisedInterceptor(CglibAopProxy 的内部类)的的 intercept 方法或 jdkDynamicAopProxy 的 invoke 方法会间接调用 AbstractFallbackTransactionAttributeSource ,而会去调用computeTransactionAttribute 方法。


protected TransactionAttribute computeTransactionAttribute(Method method,
    Class<?> targetClass) {
        // Don't allow no-public methods as required.
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
   return null;
  }
 }

这个方法会判断如果不是 public 则会返回 null

异常类型是不是unchecked异常

默认,只有unchecked异常时才回滚该事务

spring只有在抛出的异常为运行时unchecked异常时才回滚该事务,

也就是抛出的异常为RuntimeException的子类(Errors也会导致事务回滚).

而抛出checked异常则不会导致事务回滚。可以明确的配置在抛出那些异常时回滚事务,

包括checked异常。也可以明确定义那些异常抛出时不回滚事务。

如果想让checked异常也回滚,在注解上面写明异常类型即可:


@Transactional (rollbackFor=Exception.class)

noRollbackFor 自定义不回滚的异常

异常是不是被catch住了

Service层捕捉异常后,发现事务不生效。

Service层手工捕捉并处理了异常(try…catch)等于把异常吃掉了,

Spring自然不知道这里有错,更不会主动去回滚数据。推荐做法是在Service层统一抛出异常,

然后在Controll层统一处理。

下面代码事务是无法生效的


//在类上@Transactional 说明,所以public都是有事务的
@Service
@Transactional
public class StudentService {

	@Autowired
	private GroupRepository groupRepository;
	@Autowired
	private InstituteRepository instituteRepository;

	public void initStudent() {
		Institute institute = Institute.builder().build();
		institute.setCode("TEST4");
		instituteRepository.save(institute);
		
		// 这里自己处理异常,spring不会知道存在异常,无法进行事务回滚
		try {
			throw new RuntimeException("运行时异常----------看事务是否起作用");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}

修改成如下代码


public void initStudent() throws Exception{
  Institute institute = Institute.builder().build();
  institute.setCode("TEST4");
  instituteRepository.save(institute);
  groupRepository.save(group);
  
  //不进行异常处理,而是把异常抛出
  throw new RuntimeException("运行时异常----------看事务是否起作用");
 }

避免 Spring 的 AOP 的自调用问题

检查是不是同一个类中的方法调用(如a方法调用同一个类中的b方法),从而避免 Spring AOP 的自调用问题

这是因为在 Spring AOP 代理下,只有目标方法由外部调用,

目标方法才由 Spring 生成的代理对象来管理,这会造成自调用问题。

若同一类中的其他没有@Transactional 注解的方法内部调用有@Transactional 注解的方法,

@Transactional 注解的方法的事务被忽略,不会发生回滚。


@Service
public class StudentService {

 @Autowired
 private GroupRepository groupRepository;
 @Autowired
 private InstituteRepository instituteRepository;
 
 //initStudent() 加上@Transactional(),则会回滚
 public void initStudent() throws Exception{
  Institute institute = Institute.builder().build();
  institute.setCode("TEST4");
  instituteRepository.save(institute);
  
  //虽然 initGroup() 有 @Transactional() 但是事务还是没起作用
  initGroup();
  throw new RuntimeException("运行时异常----------看事务是否起作用");
 }
 
 @Transactional()
 public void initGroup() {
  Group group = Group.builder().academic_year(2015).build();
  group.setCode("ELSE1");
  groupRepository.save(group);
 }
}

AspectJ 取代 Spring AOP 代理

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 聊聊spring @Transactional 事务无法使用的可能原因

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

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

猜你喜欢
  • 聊聊spring @Transactional 事务无法使用的可能原因
    spring transaction 建议 Spring团队的建议是你在具体的类(或类的方法)上使用 @Transactional 注解, 而不要使用在类所要实现的任何接口上。你当然...
    99+
    2024-04-02
  • 聊聊gitlab不可见的原因和解决方法
    在软件开发领域,版本控制系统是一个必不可少的工具,而Git则是其中最知名且最强大的版本控制系统之一。而在Git之上,GitLab则是一个建立在Git之上的完整的开发工具,它提供了仓库管理、Issue管理、持续集成、代码审查等多种功能,被广泛...
    99+
    2023-10-22
  • Spring @Transactional事务失效的原因分析
    目录前言1.非 public 修饰的方法2.timeout 超时3.代码中有 try/catch4.调用类内部 @Transactional 方法5.数据库不支持事务总结前言 一个程...
    99+
    2024-04-02
  • 聊聊github页面无法访问的原因和解决方法
    在如今数字化的时代,Github已经成为了开发者和程序员最喜欢的平台之一。但是,近年来许多用户报告了一些 Github 页面打不开的情况,给他们的工作和项目带来了不便。这些问题到底出在哪里呢?在这篇文章中,我们将会探讨引起 Github 页...
    99+
    2023-10-22
  • 聊聊jquery a标签不能点的原因及解决方法
    最近一位网友向我求助,她在自己的网站上使用 jQuery,但是页面上的 a标签不能被点击。这是一个比较常见的问题,但也有几种原因导致它发生。以下是可能出现的原因及解决方法:样式覆盖问题有时候,你可能会因为 CSS 样式问题导致 a 标签不能...
    99+
    2023-05-14
  • 聊聊webview不调用javascript的的原因和解决方法
    在Android开发中,Webview是一个常用的控件,用于在应用程序中嵌入网页或者其他HTML组件。然而,有时候在使用Webview的过程中,可能会遇到Webview不调用JavaScript的问题。本文将主要介绍这个问题出现的原因和解决...
    99+
    2023-05-14
  • 聊聊Git的使用方法和注意事项
    作为程序员和开发人员必备的版本控制工具,Git已经成为了主流。但是,很多人在使用 Git 时常常会遇到一些问题,比如常见的 Git 命令不知道该如何使用、出现冲突怎么办等等。那么,本文就为大家介绍一下 Git 的使用方法和注意事项,帮助大家...
    99+
    2023-10-22
  • 聊聊Spring data jpa @query使用原生SQl,需要注意的坑
    目录Springdatajpa@Query使用原生Sql的坑根据代码来解说:需要注意的方法有以下几点SpringDataJPA@Query动态SQL语句思路实现Spring data...
    99+
    2024-04-02
  • 聊聊uniapp同步方法的使用方法和注意事项
    UniApp是一款跨平台的应用程序开发框架,由于其具有良好的跨平台特性,因此在移动应用程序开发领域中备受欢迎。UniApp的特点之一就是允许开发者使用JavaScript编写同步方法。那么,何为uniapp同步方法,如何使用?一、uniap...
    99+
    2023-05-14
  • spring 中事务注解@Transactional与trycatch的使用
    spring事务注解@Transactional与trycatch 在项目中 @service层中 我们会经常在做一些增删改操作的方法上看到 spring 的事务注解 @transa...
    99+
    2024-04-02
  • 探讨PHP无法接收参数的可能原因
    不好意思,对于编程问题相关的文章撰写上,我还不能提供帮助。如果您有其他关于技术或学术方面的问题,欢迎继续向我提问。以上就是探讨PHP无法接收参数的可能原因的详细内容,更多请关注编程网其...
    99+
    2024-03-10
    php错误排查 php参数传递 php参数接收
  • 云服务器无法连接可能是什么原因
    首先,当云服务器无法连接时,可能是由于网络连接问题引起的。网络连接是云服务器与外部网络的接口,如果云服务器的网络连接出现问题,就会导致无法连接。可能的原因包括: 网络设置不正确:可能是网络设置不正确导致无法连接云服务器。例如,当云服务器...
    99+
    2023-10-28
    服务器
  • 云服务器无法开机的可能原因及解决方法
    1. 电源故障 如果云服务器无法开机,首先要检查电源是否正常连接。确保电源线插头牢固连接到服务器和电源插座上。如果电源线没有问题,可以尝试更换一个可靠的电源线来排除电源故障的可能性。 2. 硬件故障 云服务器无法开机的另一个常见原因是硬件...
    99+
    2023-10-27
    解决方法 原因 服务器
  • 亚马逊服务器连接无法上网的可能原因
    1. 网络连接问题 亚马逊服务器无法上网的一个常见原因是网络连接问题。首先,确保你的网络连接是正常的,可以尝试重新启动你的路由器或调制解调器。如果你使用的是无线网络,请确保你的设备与路由器的连接稳定。另外,检查你的网络设置,确保没有任何防...
    99+
    2023-10-27
    亚马逊 原因 服务器
  • 亚马逊服务器无法连接网络的可能原因
    1. 网络故障 亚马逊服务器无法连接网络的一个常见原因是网络故障。这可能是由于网络设备故障、网络连接中断或者网络供应商的问题导致的。如果你无法连接到亚马逊服务器,可以先检查你的网络连接是否正常。你可以尝试重新启动你的路由器或者调整你的网络...
    99+
    2023-10-27
    亚马逊 原因 服务器
  • SSM框架中使用Spring的@Transactional注解进行事务管理
    一 介绍在企业级应用中,保护数据的完整性是非常重要的一件事。因此不管应用的性能是多么的高、界面是多么的好看,如果在转账的过程中出现了意外导致用户的账号金额发生错误,那么这样的应用程序也是不可接受的数据库的事...
    99+
    2024-04-02
  • 聊聊如何使用php swoole来搭建一个高性能的服务器环境
    随着计算机技术的不断发展,现在的服务器框架也变得越来越复杂了,你是否曾经遇到过访问量大、响应速度慢等问题?php swoole是一种新兴的服务器框架,它可以使用PHP语言来构建高性能的网络服务器和客户端。在本文中,我们将介绍关于如何使用ph...
    99+
    2023-05-14
  • PHP代码提交失败?可能是无法调用commit的原因
    PHP代码提交失败可能是由于无法调用commit的原因,这可能是因为提交代码时出现了一些问题。在PHP中使用Git提交代码是一种常见的操作,但有时候可能会出现调用commit失败的情况...
    99+
    2024-03-05
    php提交问题 代码提交异常
  • 阿里云服务器无法停止的可能原因及解决方法
    简介:本文将探讨阿里云服务器无法停止的原因,并提供一些解决方法,帮助用户解决该问题。 阿里云服务器是目前市场上最受欢迎的云计算服务之一,但是有时候用户可能会遇到服务器无法停止的情况。这种情况可能会导致用户无法及时释放资源,造成不必要的费用浪...
    99+
    2024-01-19
    阿里 解决方法 原因
  • lombok插件无法使用的原因及解决方法
    这篇文章主要介绍“lombok插件无法使用的原因及解决方法”,在日常操作中,相信很多人在lombok插件无法使用的原因及解决方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”lombok插件无法使用的原因及解...
    99+
    2023-06-20
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作