spring @Transactional的自调用失效问题与事务的典型错误用法剖析
@Transactional的自调用失效问题
有时候配置了注解@Transactional,但是它会失效,这里要注意一些细节问题,以避免落入陷阱。
注解@Transaction的底层实现是Spring AOP技术,而Spring AOP技术使用的是动态代理。这就意味着对于静态(static)方法和非public方法,注解@Transactional是失效的。还有一个更为隐秘的,而且在使用过程中极其容易犯错误的——自调用。
所谓自调用,就是一个类的一个方法去调用自身另外一个方法的过程。
出现这个的问题根本原因在于AOP的实现原理。由于@Transactional的实现原理是AOP,而AOP的实现原理是动态代理,而自己调用自己的过程,并不存在代理对象的调用,这样就不会产生AOP去为我们设置@Transactional配置的参数,这样就出现了自调用注解失效的问题。
为了克服这个问题,一方面可以使用两个服务类,Spring IoC容器中为你生成了RoleService的代理对象,这样就可以使用AOP,且不会出现自调用的问题。另外一方面,你也可以直接从容器中获取Service的代理对象,从IoC容器中获取RoleService代理对象。但是有一个弊端,就是从容器获取代理对象的方法有侵入之嫌,你的类需要依赖于Spring IoC容器
典型错误用法的剖析
数据事务是企业应用关注的核心内容,也是开发者最容易犯错的问题,因此笔者在这里讲解一些使用不良习惯,注意它们可以避免一些错误和性能的丢失。
错误使用Service
互联网往往采用模型—视图—控制器(Model View Controller,MVC)来搭建开发环境,因此在Controller中使用Service是十分常见的。
在Controller每调用一次带事务的service都会创建数据库事务。如果多次调用,则不在同一个事务中,这会造成不同时提交和回滚不一致的问题。每一个Java EE开发者都要注意这类问题,以避免一些不必要的错误。
过长时间占用事务
在企业的生产系统中,数据库事务资源是最宝贵的资源之一,使用了数据库事务之后,要及时释放数据库事务。换言之,我们应该尽可能地使用数据库事务资源去完成所需工作,但是在一些工作中需要使用到文件、对外连接等操作,而这些操作往往会占用较长时间,针对这些,如果开发者不注意细节,就很容易出现系统宕机的问题。
一些系统之间的通信及一些可能需要花费较长时间的操作,都要注意这个问题,放在controller层等事务外进行处理,以避免长时间占用数据库事务,导致系统性能的低下。
错误捕捉异常
带事务的service中,出现异常想要回滚时应抛出异常,而不是捕获
spring @Transactional的自调用失效问题与事务的典型错误用法剖析的更多相关文章
- Spring事务Transactional和动态代理(三)-事务失效的场景
系列文章索引: Spring事务Transactional和动态代理(一)-JDK代理实现 Spring事务Transactional和动态代理(二)-cglib动态代理 Spring事务Transa ...
- spring @Transactional 事务注解的坑
1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方法.类定义和类的 public 方法上. 2. @Transactiona ...
- Spring @Transactional事物配置无效原因
spring @transaction不起作用,Spring事物注意事项 1. 在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方 ...
- 数据库事务中的隔离级别和锁+spring Transactional注解
数据库事务中的隔离级别和锁 数据库事务在后端开发中占非常重要的地位,如何确保数据读取的正确性.安全性也是我们需要研究的问题.ACID首先总结一下数据库事务正确执行的四个要素(ACID): 原子性(At ...
- How does Spring @Transactional Really Work?--转
原文地址:http://blog.jhades.org/how-does-spring-transactional-really-work/ In this post we will do a dee ...
- Spring @Transactional ——事务回滚
工作原理运行配置@Transactional注解的测试类的时候,具体会发生如下步骤1)事务开始时,通过AOP机制,生成一个代理connection对象,并将其放入DataSource实例的某个与Dat ...
- Spring @Transactional使用的示例
Spring @Transactional使用的示例: 参考: http://blog.csdn.net/seng3018/article/details/6690527 http://blog.si ...
- Spring @Transactional 使用
Spring @Transactional是Spring提供的一个声明式事务,对代码的侵入性比较小,只需考虑业务逻辑,不需要把事务和业务搞混在一起. @Transactional 可以注解在inter ...
- Java:Spring @Transactional工作原理
本文将深入研究Spring的事务管理.主要介绍@Transactional在底层是如何工作的.之后的文章将介绍: propagation(事务传播)和isolation(隔离性)等属性的使用 事务使用 ...
随机推荐
- HDFS日志的查看总结
HDFS日志查看的两种方式:HDFS安装目录中的logs中和HDFS WEB UI上 HDFS安装目录中的logs中看日志 我们分别在master.slave1以及slave2上安装了HDFS,只 ...
- mysql wait_timeout interactive_timeout 详解
查看mysql server超时时间: msyql> show global variables like '%timeout%'; 设置mysql server超时时间(以秒为单位): 最小设 ...
- shellshock溢出攻击
实验背景 2014年9月24日,Bash中发现了一个严重漏洞shellshock,该漏洞可用于许多系统,并且既可以远程也可以在本地触发.在本实验中,需要亲手重现攻击来理解该漏洞,并回答一些问题. 什么 ...
- Mysql分布式集群
一.准备 集群: 192.168.1.191 管理节点192.168.1.192 管理节点192.168.1.193 数据节点和API节点 192.168.1.194 数据节点和API节点 安 ...
- Kubernetes 学习20调度器,预选策略及优选函数
一.概述 1.k8s集群中能运行pod资源的其实就是我们所谓的节点,也称为工作节点.master从本质上来讲,他其实是运行整个集群的控制平面组件的比如apiserver,scheal,controlm ...
- Kubernetes 学习7 Pod控制器应用进阶2
一.容器探测器 1.所谓的容器探测无非就是我们在里面设置了一些探针,或者称之为传感器来获取相应的数据作为判定其存活与否或就绪与否的标准,目前k8s所支持的存活性和就绪性探测方式都是一样的. 2.k8s ...
- QGraphicsView,QGraphicsScene,QGraphicsItem
参考:Qt4 开发实践第八章 图形视图QGraphicsView #ifndef DRIVEDGRAPH_H #define DRIVEDGRAPH_H #include <QObject> ...
- PHP CURL 错误码说明
curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));//一般不加 <?php return [ '1'=> ...
- 数组思维 -- join的一些用法感悟
组合字符串的时候, 组合 sql 的时候, 使用join 会非常有用, join and 记得前端时间去看面试题的时候, 总会出一个小的性能题目, 就是 如果有大量的字符串处理的时候, 怎么 ...
- c#调用phantomjs 将 网页 存为 PDF
一. 下载 phantomjs 具体下载方式 不再详细说明了. 二. 创建一个 rasterize.js 文件 (放在哪里都行, 我这里是放在了项目中) . 代码内容如下 var page = req ...