springboot 配置全局响应数据_spring boot 全局事务配置
我发现很多开源的springBoot项目,使用事务都是 直接使用 事务注解。并没有配置全局事务的。
其实目前现在不是新人程序员就以为 事务就只能靠加注解来控制了。根本没听说过全局事务配置。
网上很多全局事务其实都是不够好的。都是抄来抄去的。真的不知道能不能用。
其实这样很不好的。
写代码的时候如果漏了加上事务注解,那异常不回滚太可怕了
如果写代码的时候都需要手动加上注解,多费事啊。配置全局事务注解多省事。
配置代码
package com.door.config;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.interceptor.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/** 全局事务控制,防止漏加 事务注解,也就是说开发中可以不用加事务注解了 */
@Configuration
@Aspect
public class TransactionConfig {
private static final int TX_METHOD_TIMEOUT = 60;
private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.door..service..*(..))";
@Autowired private PlatformTransactionManager transactionManager;
@Bean
public TransactionInterceptor txAdvice() {
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
RuleBasedTransactionAttribute readOnly = new RuleBasedTransactionAttribute();
readOnly.setReadOnly(true);
readOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// 禁止使用这种 。这种会导致 只读事务不生效的。而且 可以 在代码里面 提交事务的
// readOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
RuleBasedTransactionAttribute required = new RuleBasedTransactionAttribute();
required.setRollbackRules(
Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
required.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// 单位是 秒
required.setTimeout(TX_METHOD_TIMEOUT);
Map txMap = new HashMap<>(50);
txMap.put("add*", required);
txMap.put("save*", required);
txMap.put("insert*", required);
txMap.put("update*", required);
txMap.put("delete*", required);
txMap.put("create*", required);
txMap.put("init*", required);
txMap.put("submit*", required);
txMap.put("remove*", required);
txMap.put("edit*", required);
txMap.put("modify*", required);
txMap.put("batch*", required);
txMap.put("mass*", required);
txMap.put("handle*", required);
txMap.put("exec*", required);
txMap.put("import*", required);
txMap.put("set*", required);
txMap.put("get*", readOnly);
txMap.put("select*", readOnly);
txMap.put("list*", readOnly);
txMap.put("query*", readOnly);
txMap.put("find*", readOnly);
txMap.put("count*", readOnly);
txMap.put("page*", readOnly);
txMap.put("all*", readOnly);
txMap.put("*", readOnly);
source.setNameMap(txMap);
return new TransactionInterceptor(transactionManager, source);
}
// @Bean 这种方式不够好,不能配置回滚异常。 其实和上面的方式 的原理是一样的。
// public TransactionInterceptor txAdvice() {
//
// DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute();
// txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
// txAttr_REQUIRED.setTimeout(TX_METHOD_TIMEOUT);
//
// DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute();
// txAttr_REQUIRED_READONLY.setPropagationBehavior(
// TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
// txAttr_REQUIRED_READONLY.setReadOnly(true);
//
// NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
// source.addTransactionalMethod("add*", txAttr_REQUIRED);
// source.addTransactionalMethod("save*", txAttr_REQUIRED);
// source.addTransactionalMethod("delete*", txAttr_REQUIRED);
// source.addTransactionalMethod("update*", txAttr_REQUIRED);
// source.addTransactionalMethod("exec*", txAttr_REQUIRED);
// source.addTransactionalMethod("set*", txAttr_REQUIRED);
//
// // source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);
// // source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
// // source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
// // source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
// // source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
// source.addTransactionalMethod("*", txAttr_REQUIRED_READONLY);
//
//
//
// return new TransactionInterceptor(transactionManager, source);
// }
@Bean
public Advisor txAdviceAdvisor() {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
return new DefaultPointcutAdvisor(pointcut, txAdvice());
}
}
全局事务控制优先级高还是 事务注解优先级高?
这个就是 看 配置的 AOP拦截器的 排序来定义了。默认是 全局事务控制的优先级高。
而且 使用了 事务注解也是不生效的。因为 PROPAGATION_REQUIRED 的事务传播行为就是 如果之前已经有了一个事务了。
那么不会创建新的事务,而是 用回之前的事务。
TransactionDefinition.PROPAGATION_NOT_SUPPORTED 不要配置
以前同事就是这样配置的,之前一直都没有注意到,今天测试 只读事务的时候,才发现根本没有起作用。
还是可以在 方法里面执行 写数据库操作的,而且并没有事务控制!!
source.setNameMap(txMap); 与 addTransactionalMethod 是一样的原理
source.setNameMap(txMap); 的源码 就是 循环调用 addTransactionalMethod 方法
搜索很多都是 DefaultTransactionAttribute 这样的代码,并不能定义Execption异常类型回滚
xml 全局事务配置
没有使用spring boot 开发之前的老项目,基本都是 使用 xml 进行配置全局事务拦截的
参考
springboot 配置全局响应数据_spring boot 全局事务配置相关推荐
- springboot初始化加载数据_Spring Boot配置数据加载大全
关于注入数据说明 1.不通过配置文件注入数据 通过@Value将外部的值动态注入到Bean中,使用的情况有: 注入普通字符串 注入操作系统属性 注入表达式结果 注入其他Bean属性:注入Student ...
- springboot 配置全局响应数据_SpringBoot如何读取配置文件参数并全局使用
{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...
- springboot 控制台输出错误信息_Spring boot使用logback实现日志配置
前言 日志是我们系统必备的功能之一,可以帮助我们开发人员定位系统的异常.错误以及运行流程的重要的工具.今天老顾就来介绍一下Spring boot的默认的logback日志框架. 常用日志组件 java ...
- springboot controller访问不到_Spring Boot 开篇:快速入门
背景 想想之前搭建一个WEB项目,不管项目的功能简单或复杂,都需要哪些步骤: 配置 web.xml,加载 Spring 和 Spring mvc 配置数据库连接.配置 Spring 事务 配置加载配置 ...
- java+swagger+侵入_Spring boot+Swagger配置无侵入式Restful接口(二)
maven依赖自动配置 额,看了前面第一种配置方式,是不是感觉有点麻烦呢?我也觉得,到时候去掉的时候,还需要进行删除配置啊,一大堆,还有可能到时候根本不知道. 所以,我决定自己写个让它自己就可以完成配 ...
- Ubuntu配置全局系统代理(常用工具配置)
Ubuntu配置全局系统代理(常用工具) 问题描述 解决方法 配置系统代理 终端部分配置 配置apt代理 配置curl,wget,pip代理 git相关代理的设置 配置docker代理 问题描述 公司 ...
- springboot 上传异常捕获_Spring Boot 全局异常处理(下)
可以搜索微信公众号[Jet 与编程]查看更多精彩文章 背景 在上篇[链接]中介绍了 Spring Boot 全局异常处理的一种方式,但那是一种全局性的容错机制,目的是把 Spring Boot 默认的 ...
- springboot日志配输出路径配置_Spring Boot 日志配置方法(超详细)
默认日志 Logback : 默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台.在运行应用程序和其他例子时,你应该已经看到很多INFO级别的日志了. 从上图 ...
- springboot传入json和文件_Spring Boot之 Controller 接收参数和返回数据总结(包括上传、下载文件)...
server: port: 8088 servlet: context-path: /sid spring: mvc: view: prefix: / suffix: .html /** * 返回界面 ...
最新文章
- ORBSLAM-Altas:多地图SLAM
- xampp无法启动apache,提示terminating worker thread 0
- 公布.NET 框架库源代码(转)
- 汽车线束测试软件,Aigtek线束测试仪,汽车线束测试_高精度自动测试_操作简单...
- JS知识点笔记-常用方法
- python变量类型是动态的_【Python】python动态类型
- SVM支持向量机算法详解
- 前端项目使用阿里图标
- zemax中如何和matlab中通信,如何在Zemax与Matlab间通信
- python excel行列转置_用powershell+excel行列转置三步走
- java游戏和flash游戏区别,小游戏的基本种类
- 支付宝sdk集成,报系统繁忙 请稍后再试(ALI64)
- vagrant给vmbox创建虚拟机及docker安装mysql和redis
- OpenCV:minMaxLoc vs minMaxIdx
- Badboy安装和介绍
- 强化学习入门 Q-learning与SARSA
- [js高手之路] html5 canvas教程 - 绘制七巧板
- 新生儿肚脐清洗小窍门
- Syncthing+蒲公英oray快速实现异地文件同步
- oracle bam教程,Oracle业务活动监控(BAM)和业务规则