我发现很多开源的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 全局事务配置相关推荐

  1. springboot初始化加载数据_Spring Boot配置数据加载大全

    关于注入数据说明 1.不通过配置文件注入数据 通过@Value将外部的值动态注入到Bean中,使用的情况有: 注入普通字符串 注入操作系统属性 注入表达式结果 注入其他Bean属性:注入Student ...

  2. springboot 配置全局响应数据_SpringBoot如何读取配置文件参数并全局使用

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  3. springboot 控制台输出错误信息_Spring boot使用logback实现日志配置

    前言 日志是我们系统必备的功能之一,可以帮助我们开发人员定位系统的异常.错误以及运行流程的重要的工具.今天老顾就来介绍一下Spring boot的默认的logback日志框架. 常用日志组件 java ...

  4. springboot controller访问不到_Spring Boot 开篇:快速入门

    背景 想想之前搭建一个WEB项目,不管项目的功能简单或复杂,都需要哪些步骤: 配置 web.xml,加载 Spring 和 Spring mvc 配置数据库连接.配置 Spring 事务 配置加载配置 ...

  5. java+swagger+侵入_Spring boot+Swagger配置无侵入式Restful接口(二)

    maven依赖自动配置 额,看了前面第一种配置方式,是不是感觉有点麻烦呢?我也觉得,到时候去掉的时候,还需要进行删除配置啊,一大堆,还有可能到时候根本不知道. 所以,我决定自己写个让它自己就可以完成配 ...

  6. Ubuntu配置全局系统代理(常用工具配置)

    Ubuntu配置全局系统代理(常用工具) 问题描述 解决方法 配置系统代理 终端部分配置 配置apt代理 配置curl,wget,pip代理 git相关代理的设置 配置docker代理 问题描述 公司 ...

  7. springboot 上传异常捕获_Spring Boot 全局异常处理(下)

    可以搜索微信公众号[Jet 与编程]查看更多精彩文章 背景 在上篇[链接]中介绍了 Spring Boot 全局异常处理的一种方式,但那是一种全局性的容错机制,目的是把 Spring Boot 默认的 ...

  8. springboot日志配输出路径配置_Spring Boot 日志配置方法(超详细)

    默认日志 Logback : 默认情况下,Spring Boot会用Logback来记录日志,并用INFO级别输出到控制台.在运行应用程序和其他例子时,你应该已经看到很多INFO级别的日志了. 从上图 ...

  9. springboot传入json和文件_Spring Boot之 Controller 接收参数和返回数据总结(包括上传、下载文件)...

    server: port: 8088 servlet: context-path: /sid spring: mvc: view: prefix: / suffix: .html /** * 返回界面 ...

最新文章

  1. ORBSLAM-Altas:多地图SLAM
  2. xampp无法启动apache,提示terminating worker thread 0
  3. 公布.NET 框架库源代码(转)
  4. 汽车线束测试软件,Aigtek线束测试仪,汽车线束测试_高精度自动测试_操作简单...
  5. JS知识点笔记-常用方法
  6. python变量类型是动态的_【Python】python动态类型
  7. SVM支持向量机算法详解
  8. 前端项目使用阿里图标
  9. zemax中如何和matlab中通信,如何在Zemax与Matlab间通信
  10. python excel行列转置_用powershell+excel行列转置三步走
  11. java游戏和flash游戏区别,小游戏的基本种类
  12. 支付宝sdk集成,报系统繁忙 请稍后再试(ALI64)
  13. vagrant给vmbox创建虚拟机及docker安装mysql和redis
  14. OpenCV:minMaxLoc vs minMaxIdx
  15. Badboy安装和介绍
  16. 强化学习入门 Q-learning与SARSA
  17. [js高手之路] html5 canvas教程 - 绘制七巧板
  18. 新生儿肚脐清洗小窍门
  19. Syncthing+蒲公英oray快速实现异地文件同步
  20. oracle bam教程,Oracle业务活动监控(BAM)和业务规则

热门文章

  1. 记一次telnet自定义端口不通(阿里云平台)
  2. 某企业虚拟化平台时间同步异常排查
  3. volley全然解析
  4. RIP路由协议基本配置
  5. 线段树(Segment Tree)
  6. 条款27:尽量少做转型动作
  7. HDUOJ---------2255奔小康赚大钱
  8. 和php结合实现分页js代码,无JS,完全php面向过程数据分页实现代码
  9. markdown 折叠目录_Markdown秒变PPT
  10. android地图三段滑动,android – 像谷歌地图一样滑动BottomSheet