Seata的这些安保机制是否会让你更放心

news2024/11/15 14:08:04

一、背景

SpringBoot 项目,通过引入seata-spring-boot-starter来接入 Seata,Seata 的能力会通过 SpringBoot 的自动装配机制来引入。在学习的时候是梳理有什么强大的、科技感十足的能力,但在试点的时候则更多考虑的是有哪些安保机制,比如通过什么开关来启停某某功能,以保护程序。今天就梳理有什么安保机制,划清能力边界,让使用者不必太过担心;生产中安全永远是第一的嘛。

二、认知拉齐-starter 中提供什么能力

第二部分若真不熟悉,看不懂可跳过进入第三部分。

Pom 依赖

<dependency>
   <groupId>io.seata</groupId>
   <artifactId>seata-spring-boot-starter</artifactId>
   <version>${seata.version}</version>
</dependency>
复制代码

梳理自动装配类,直接从seata-spring-boot-starter中找文件spring.factories,其中有以下自动装配类:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.seata.spring.boot.autoconfigure.SeataDataSourceAutoConfiguration,\
io.seata.spring.boot.autoconfigure.SeataAutoConfiguration,\
io.seata.spring.boot.autoconfigure.HttpAutoConfiguration,\
io.seata.spring.boot.autoconfigure.SeataSagaAutoConfiguration
复制代码

1) SeataDataSourceAutoConfiguration

Seata 的 AT 和 AX 模式是基于数据源代理实现的,SeataDataSourceAutoConfiguration 中自动对数据源做了代理,不用使用者手动实现代理。

2) SeataAutoConfiguration

  • 构建全局事务扫描器GlobalTransactionScanner,注入到容器中,其内部做 2 件事情
    • 会初始化 TM、RM 客户端
    • 扫描Bean,对添加了全局事务注解的类(@GlobalTransactional@GlobalLock@TwoPhaseBusinessAction)生成代理对象,添加对应的拦截器(拦截器内补充分布式事务的能力)
  • 注入一个FailureHandler,其默认实现DefaultFailureHandlerImpl中只会打印错误日志,建议重写,异常发生时及时告知使用者。

3)HttpAutoConfiguration

  • 应用通过 http 协议通信时,通过 http header 透传 xid

4)SeataSagaAutoConfiguration

  • Saga 模式才用的到,目前还不了解

三、探索 Seata 所提供的安保机制

3.1 引入 seata-spring-boot-starter 之后 Seata 功能就启动了嘛?

答案:不,有一个开关seata.enabled,若为 true:则启动自动装配;若为 false:则不启用自动装配。比如就在开发测试环境验证,暂且还不上生产,就可以通过这个开关来实现。

1)详情:

application.yml 中留意这个配置:

seata:
  enabled: true
复制代码

上述几个自动装配类中都有激活条件,ConditionalOnPropertyConditionalOnExpression其用意为,当seata.enabled=true的情况下,自动装配类才生效。

@ConditionalOnProperty(prefix = SEATA_PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
...
@ConditionalOnExpression("${seata.enabled:true}
复制代码

3.2 数据源是被自动代理嘛?

答案 :不,有开关

1)详情:

seata.enableAutoDataSourceProxy:true,若为 true:则启动自动代理,若为 false:则不启用自动代理。

seata:
  enableAutoDataSourceProxy: true
复制代码

生效源码见下方:

@ConditionalOnExpression("${seata.enabled:true} && ${seata.enableAutoDataSourceProxy:true} && ${seata.enable-auto-data-source-proxy:true}")
public class SeataDataSourceAutoConfiguration {
复制代码

3.3 所有的数据源都会被代理嘛

  • 答案:不,有两种办法来避免

1)方法 1:自动代理+排除法:

  • 开启自动代理seata.enableAutoDataSourceProxy:true
  • 指定不需要被代理的 DataSouce 的 bean 名称(数组形式)
    seata:
        enableAutoDataSourceProxy: true
        excludesForAutoProxying: dataSource1,dataSource2,dataSource3
    复制代码

2)方法 2:手动代理

  • 关闭自动代理 seata.enableAutoDataSourceProxy:false
  • 手动方式对数据源做代理,参考这个代码
    SeataDataSourceProxy buildProxy(DataSource origin, String proxyMode) {
    if (BranchType.AT.name().equalsIgnoreCase(proxyMode)) {
        return new DataSourceProxy(origin);
    }
    if (BranchType.XA.name().equalsIgnoreCase(proxyMode)) {
        return new DataSourceProxyXA(origin);
    }
    throw new IllegalArgumentException("Unknown dataSourceProxyMode: " + proxyMode);
    }
    复制代码

3.4 加了 Seata 事务注解就生效了嘛,被人不小心复制走的有办法不生效嘛

答案:算是有,目前已知有以下几种方法

1) 方法 1: 可指定 Seata 注解扫描的包路径,根据情况结合 排除 bean 名称的方法一起用

// add scannable packages
GlobalTransactionScanner.addScannablePackages(seataProperties.getScanPackages());
// add excludeBeanNames
GlobalTransactionScanner.addScannerExcludeBeanNames(seataProperties.getExcludesForScanning());
复制代码

2) 方法 2:使用显式的编程 API 开启事务(待验证)

GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
try {
    tx.begin(300000, "test-group");
    accountService.addUserInfo(account.getAccountNo(),account.getAccountName(),account.getTip());
    storeService.decreaseStock(store);
    tx.commit();
} catch (TransactionException e) {
    try {
        tx.rollback();
    } catch (TransactionException transactionException) {
        transactionException.printStackTrace();
    }
    //e.printStackTrace();
}
复制代码

3.5 Seata 的全局事务能力是否可以动态启停?

答案:可以

1) 场景 1:先禁用再启用,可通过service.disableGlobalTransaction=true在启东时禁用,然后在运行期变更配置为 false ,如果配置中心能力够强,还可单独给某个实例激活全局事务。对应的源码如下

public void onChangeEvent(ConfigurationChangeEvent event) {
    if (ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION.equals(event.getDataId())) {
        disableGlobalTransaction = Boolean.parseBoolean(event.getNewValue().trim());
        //compareAndSet(expect, update), 要想更新成功的话,那么这个expect的值一定是1,否则是不会被更新的。
        //即配置中心下达启用分布式锁,且客户端未启动
        if (!disableGlobalTransaction && initialized.compareAndSet(false, true)) {
            LOGGER.info("{} config changed, old value:true, new value:{}", ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION,
                    event.getNewValue());
            initClient();
            ConfigurationCache.removeConfigListener(ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION, this);
        }
    }
}
复制代码

2)场景 2:在运行期关闭已运行的全局事务能力,可通过service.disableGlobalTransaction=true在运行期,关闭全局事务

3.6 Seata 是否有降级能力?

答案:有,有两个维度的降级能力,

1)方法 1:使用 3.5 中的是否禁用全局事务手动降级

  1. 方法 2:自动降级。配置个阈值,当自检周期(滑动时间窗口内)异常次数达到阈值后就禁用全局事务,当自检周期(滑动时间窗口内)连续成功后则恢复。通过设置client.tm.degradeCheck=true,结合degradeCheckAllowTimesdegradeCheckPeriod来设置阈值与自检周期;如下示例:
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
复制代码

3.7 Seata 是否可以不代理无需分布式事务的数据源?

答案:可以变通实现,有 2 种方法。

1)方法 1:DataSouce 从一个变成 2 个,即一个是原始 DataSource,另一个基于原始的 DataSource 代理,生成一个代理的 DataSouce,在使用到分布式事务的逻辑中才使用代理的 DataSouce,不使用分布式事务的逻辑中使用原始的 DataSource。但这种两个 DataSouce 其实是同一个,会使用相同的连接池(用连接池的情况下)。

2)方法 2:使用两个完全独立的 DataSouce,其中一个做与分布式事务无关的逻辑;另一个做代理,提供分布式事务的能力。

3.8 Seata 的全局事务能力是否可以按请求属性启用

答案:可以有,这里提供 1 种方法。

1)方法 1:把一个方法拆分,根据流量属性判断是否需要进入到开启分布式事务的方法中。

function A(param){
    if(param.xx == 开启分布式事务){
        A-2(param)
    }else{
        A-1(param)
    }
}
function A-1(param){
}
//A-2上添加分布式事务注解
fcuntion A-2(param){
}
复制代码

四、总结

本篇梳理的内容是:当我们在试点分布式事务系统 Seata 的时候,对系统安全方面可能有哪些诉求,以及 Seata 能提供怎样的保护能力。毕竟我们引入新系统是为了解决问题而不是创造问题,没有足够使用经验,对内部机制掌握不够的情况下,全面的掌握 Seata 所提供的安保机制,按需禁用或开启、将新能力和老逻辑划清边界、以最小化测试单元的原则来推进,应该会更加顺利。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/56813.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

将内网网站发布上线【免服务器】

什么是cpolar&#xff1f; cpolar是一个非常强大的内网穿透工具&#xff0c;开发调试的必备利器。 它可以将本地内网服务器的HTTP、HTTPS、TCP协议端口映射为公网地址端口&#xff0c;使得公网用户可以轻松访问您的内网服务器&#xff0c;无需部署至公网服务器。支持永久免费使…

Mysql进阶学习(七)联合查询与DML语言

Mysql进阶学习&#xff08;七&#xff09;联合查询与DML语言进阶9&#xff1a;联合查询语法&#xff1a;特点&#xff1a;★案例DML语言1、插入语句1.1.插入的值的类型要与列的类型一致或兼容1.2.不可以为null的列必须插入值。可以为null的列如何插入值&#xff1f;1.3.列的顺序…

机械转码日记【26】二叉搜索树

目录 前言 1.二叉搜索数的概念 2.二叉搜索树的实现 2.1 基本架构 2.2二叉搜索树的插入 2.2.1普通版本 2.2.2递归版本 2.3二叉搜索树的查找 2.3.1普通版本 2.3.2递归版本 2.4二叉搜索树的删除 2.4.1普通版本代码 2.4.2递归版本代码 2.5搜索树的析构函数 2.6搜…

电脑黑屏按什么键恢复?只需要3个键就可以解决黑屏

今天和大家聊一聊电脑黑屏这个问题。相信大家都遇到过电脑黑屏&#xff0c;但是却不知道该如何解决&#xff0c;今天就来给大家分享一些处理方法。如果是电脑黑屏的话&#xff0c;一般情况下&#xff0c;只需要三个键就可以解决问题&#xff0c;电脑黑屏按什么键恢复&#xff1…

【Matplotlib绘制图像大全】(九):Matplotlib使用xticks()修改x轴刻度位置信息

前言 大家好,我是阿光。 本专栏整理了《Matplotlib绘制图像大全》,内包含了各种常见的绘图方法,以及Matplotlib各种内置函数的使用方法,帮助我们快速便捷的绘制出数据图像。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmMatp…

提到Canvas,必须好好唠唠它的图像操作能力

前情提要 接续一下之前对Canvas的探索。本篇分享一下对图像操作的阅读和研究。 日常开发中&#xff0c;时常遇到对图像的处理的场景。精美的图像做为背景或者场景&#xff0c;相对会吸引人。 Canvas图像API十分强大。可以通过Canvas图像API加载图像数据&#xff0c;进行裁剪…

ubuntu篇---ubuntu安装mysql教程

ubuntu篇---ubuntu安装mysql教程一. 首先卸载掉原来的mysql第一步&#xff0c;依次执行下面的语句第2步 清理残留数据第三步 验证原有主机上是否安装mysql&#xff1a;二. 安装mysql三. 修改密码加粗样式ubuntu安装mysql教程 一. 首先卸载掉原来的mysql 第一步&#xff0c;依…

深入理解蓝牙BLE之“扩展广播”

目录 前言&#xff1a; 4.2版本广播&#xff1a; 5.0版本广播&#xff1a; 实现原理&#xff1a; 格式定义&#xff1a; 广播事件类型&#xff1a; 扩展广播&#xff1a; 周期广播&#xff1a; 广播集&#xff1a; HCI接口定义&#xff1a; 4.2版本&#xff1a; 5.…

正式练习的第一个Python功能:加法计算

我本身有着C/C的功底&#xff0c;最近开始自学python&#xff0c;包括网上找教程&#xff0c;买书看。不确定我这种有其他编程语言经验的再学新的语言算不算零基础&#xff0c;总之书就买的《零基础学Python程序设计》。鉴于自己之前已经看过一段时间&#xff0c;这个程序也就不…

[附源码]Python计算机毕业设计SSM开放实验室管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

微服务框架 SpringCloud微服务架构 10 使用Docker 10.3 容器命令介绍

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 SpringCloud微服务架构 文章目录微服务框架SpringCloud微服务架构10 使用Docker10.3 容器命令介绍10.3.1 容器相关命令10 使用Docker 10.3 …

一类综合的模糊化自适应滑模控制

目录 前言 1.系统描述 2.控制器设计 3.模糊化设计 3.1构造模糊系统 3.2自适应律设计 4仿真分析 4.1仿真系统 4.2仿真结果 前言 上几篇文章分别介绍了模糊化切换增益(也就是模糊化外界扰动d)、模糊化系统部分的不确定项f、模糊化整个切换项&#xff0c;其原理分别为利…

如何制作gif图片?

文章目录一、下载LICEcap【制作gif的工具】&#xff08;按步骤安装即可&#xff09;二、LICEcap的使用录制步骤&#xff1a;三、录制的gif效果展示一、下载LICEcap【制作gif的工具】&#xff08;按步骤安装即可&#xff09; LICEcap是一款简洁易用的动画屏幕录制软件&#xff…

HTML CSS大学生期末网页大作业 DW个人网页设计 人物介绍 历史人物岳飞介绍

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

智慧工地技术方案

二、 系统概述 建筑工地是一个安全事故多发的场所。目前&#xff0c;工程建设规模不断扩大&#xff0c;工艺流程纷繁复杂&#xff0c;如何完善现场施工现场管理&#xff0c;控制事故发生频率&#xff0c;保障文明施工一直是施工企业、政府管理部门关注的焦点。尤其随着社会的…

Elasticsearch_第3章_ elasticsearch_进阶

Elasticsearch_第3章_ elasticsearch_进阶 文章目录Elasticsearch_第3章_ elasticsearch_进阶0.学习目标1.数据聚合1.1.聚合的种类1.2.DSL实现聚合1.2.1.Bucket聚合语法1.2.2.聚合结果排序1.2.3.限定聚合范围1.2.4.Metric聚合语法1.2.5.小结1.3.RestAPI实现聚合1.3.1.API语法1.…

Redis数据结构

一.NoSQL 1.认识NoSQL 关系型数据库&#xff1a;结构化&#xff08;有很多约束&#xff09;&#xff0c;关联的&#xff08;数据库会自己维护数据之间的关联&#xff0c;如外键&#xff09;&#xff0c;SQL查询&#xff08;语法统一&#xff09;&#xff0c;满足事务ACID的特性…

C# Winform 文本面板带滚动条

Winform 中如果需要在一个固定大小的面板中显示一些内容&#xff0c;并且面板能上下拖动&#xff0c;将所有的内容完整的展示&#xff0c;这种需求很常见&#xff0c;下面就演示如何实现的吧 效果&#xff1a; 1.新建一个winform 项目&#xff0c;在界面中拖入一个Panel 将 p…

港科夜闻|香港科技大学校长叶玉如教授,新加坡国立大学曾运雄博士:发现阿尔茨海默病新疗法...

关注并星标每周阅读港科夜闻建立新视野 开启新思维1、香港科技大学校长叶玉如教授、新加坡国立大学曾运雄博士&#xff1a;发现阿尔茨海默病新疗法。由中科院院士、香港科技大学校长叶玉如教授&#xff0c;及新加坡国立大学感染、免疫与炎症研究所的曾运雄博士共同领导的团队研…

rxjs pipeable operators(下)

rxjs pipeable operators&#xff08;下&#xff09; 这一篇主要就是讲 flattening operators&#xff0c;像其他的 pipeable 一样&#xff0c; flattening operators 内部会 subscribe 每一个传进来的 Observable&#xff0c;并且将其返回一个新的 Observable。不过它可以将 …