<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## :-: springcloud 整合Seata實現分布式事務 ## Seata簡介 [https://github.com/seata](https://github.com/seata) Seata(Simple Extensible Autonomous Transaction Architecture) 是 阿里巴巴開源的分布式事務中間件,以高效并且對業務 0 侵入的方式,解決微服務場景下面臨的分布式事務問題。 ## Seata解決方案 先介紹 `Seata` 分布式事務的幾種角色: * `Transaction Coordinator(TC)`: ?全局事務協調者,用來協調全局事務和各個分支事務(不同服務)的狀態, 驅動全局事務和各個分支事務的回滾或提交。 * `Transaction Manager?`: ?事務管理者,業務層中用來開啟/提交/回滾一個整體事務(在調用服務的方法中用注解開啟事務)。 * `Resource Manager(RM)`: ?資源管理者,一般指業務數據庫代表了一個分支事務(`Branch Transaction`),管理分支事務與 `TC` 進行協調注冊分支事務并且匯報分支事務的狀態,驅動分支事務的提交或回滾。 典型的分布式事務周期包括以下步驟: * TM向TC請求開啟一個全局事務,TC給TM返回一個全局事務的XID; * XID在微服務調用鏈之間傳遞; * RM向TC注冊XID下的分支事務; * TM根據XID向TC發出提交或者回滾的請求; * TC根據XID使RM提交或者回滾。 Seata 也是從兩段提交演變而來的一種分布式事務解決方案,提供了 AT、TCC、SAGA 和 XA 等事務模式,這里重點介紹 AT模式。 #### AT模式 1、基于支持本地 ACID 事務的關系型數據庫,整體機制是2PC的演變。 ~~~ 一階段:業務數據和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源。 二階段:提交異步化,成功則批量地刪除相應回滾日志記錄,回滾則通過回滾日志進行反向補償。 ~~~ 2、寫隔離。 ~~~ 1)一階段本地事務提交前,需要確保先拿到全局鎖。 2)拿不到全局鎖,不能提交本地事務;拿到全局鎖,提交本地事務并插入undo_log記錄。 3)拿全局鎖的嘗試被限制在一定范圍內,超出范圍將放棄,并根據undo_log記錄回滾本地事務,釋放本地鎖。 ~~~ 3、讀隔離。 ~~~ 1)在數據庫本地事務隔離級別 讀已提交(Read Committed) 或以上的基礎上,Seata(AT 模式) 的默認全局隔離級別是 讀未提交(Read Uncommitted)。 理解:在全局事務提交之前,本地事務會先提交,這時候查詢數據,對于本地庫是Read Committed, 對于全局來說是 Read Uncommitted。 2)如果要求全局的讀已提交,目前 Seata 的方式是通過 SELECT FOR UPDATE 語句的代理。 ~~~ ## **springcloud 整合Seata實現分布式事務** 項目使用的是SpringBoot 2.x + SpringCloud,注冊中心使用的是nacos ### **一、seata-server搭建** 1、下載最新版seata-server-1.4.0.zip 2、修改registry.conf。 registry.type 改成nacos 然后配置nacos 如下 ``` registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" loadBalance = "RandomLoadBalance" loadBalanceVirtualNodes = 10 nacos { application = "seata-server" serverAddr = "127.0.0.1:8848" group = "SEATA_GROUP" namespace = "" cluster = "default" username = "" password = "" } ``` 3、使用file.conf,store.mode選擇db,修改連接的數據庫屬性,其他的默認即可。 ``` db { datasource = "druid" ## mysql/oracle/postgresql/h2/oceanbase etc. dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" url = "jdbc:mysql://*************.mysql.rds.aliyuncs.com:3306/hj_seata?useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT&zeroDateTimeBehavior=convertToNull&useSSL=false" user = "root" password = "****" minConn = 5 maxConn = 100 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 } ``` 4、在數據庫中加入三個表。 ``` DROP TABLE IF EXISTS `branch_table`; CREATE TABLE `branch_table` ( `branch_id` bigint(20) NOT NULL, `xid` varchar(128) NOT NULL, `transaction_id` bigint(20) DEFAULT NULL, `resource_group_id` varchar(32) DEFAULT NULL, `resource_id` varchar(256) DEFAULT NULL, `lock_key` varchar(128) DEFAULT NULL, `branch_type` varchar(8) DEFAULT NULL, `status` tinyint(4) DEFAULT NULL, `client_id` varchar(64) DEFAULT NULL, `application_data` varchar(2000) DEFAULT NULL, `gmt_create` datetime DEFAULT NULL, `gmt_modified` datetime DEFAULT NULL, PRIMARY KEY (`branch_id`), KEY `idx_xid` (`xid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `global_table` ( `xid` varchar(128) NOT NULL, `transaction_id` bigint(20) DEFAULT NULL, `status` tinyint(4) NOT NULL, `application_id` varchar(64) DEFAULT NULL, `transaction_service_group` varchar(64) DEFAULT NULL, `transaction_name` varchar(64) DEFAULT NULL, `timeout` int(11) DEFAULT NULL, `begin_time` bigint(20) DEFAULT NULL, `application_data` varchar(2000) DEFAULT NULL, `gmt_create` datetime DEFAULT NULL, `gmt_modified` datetime DEFAULT NULL, PRIMARY KEY (`xid`), KEY `idx_gmt_modified_status` (`gmt_modified`,`status`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; CREATE TABLE `lock_table` ( `row_key` varchar(128) NOT NULL, `xid` varchar(96) DEFAULT NULL, `transaction_id` mediumtext, `branch_id` mediumtext, `resource_id` varchar(256) DEFAULT NULL, `table_name` varchar(32) DEFAULT NULL, `pk` varchar(32) DEFAULT NULL, `gmt_create` datetime DEFAULT NULL, `gmt_modified` datetime DEFAULT NULL, PRIMARY KEY (`row_key`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; ``` 5、在bin目錄下,啟動server服務,默認是8091端口。 ### **二、springCloud 項目整合** **Springboot:2.3.2.RELEASE** **springCloud alibaba:2.2.0.RELEASE** **springCloud :Hoxton.RELEASE** **搭建2個微服務項目hj-seata-client1 hj-seata-client2 調用關系為 hj-seata-client調用hj-seata-client1的服務** **1、配置** ~~~ <dependencies> <dependency> <groupId>com.hjf.mall</groupId> <artifactId>hj-common</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-nacos-discovery</artifactId> </dependency> <!--mysql: 數據庫鏈接驅動工具 8.0版本可以對應數據庫5.6、5.7、8.0 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--java工具類 Bean注解簡化開發--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </dependency> <!-- mybatis-plus start --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus-boot-starter.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-extension</artifactId> <version>${mybatis-plus-boot-starter.version}</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-seata</artifactId> <exclusions> <exclusion> <artifactId>seata-spring-boot-starter</artifactId> <groupId>io.seata</groupId> </exclusion> </exclusions> </dependency> <!--阿里分布式事務--> <dependency> <groupId>io.seata</groupId> <artifactId>seata-spring-boot-starter</artifactId> <version>1.4.0</version>--> </dependency> </dependencies> <dependencyManagement> <dependencies> <!--cloud依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>${spring-cloud-alibaba.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ~~~ **application.yml** ***** ~~~ server: port: 6002 spring: main: allow-bean-definition-overriding: true application: name: seata-B # --------------cloud配置------------------ cloud: nacos: discovery: server-addr: 127.0.0.1:8848 #注冊服務控制中心 # 這里配置分組 alibaba: seata: tx-service-group: my_test_tx_group #------------數據庫鏈接----------------------------- datasource: url: jdbc:mysql://****.mysql.rds.aliyuncs.com:3306/hj_mall?useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT&zeroDateTimeBehavior=convertToNull&useSSL=false username: root password: *** driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: mapper-locations: classpath:/mapper/*Mapper.xml #實體掃描,多個package用逗號或者分號分隔 typeAliasesPackage: com.hjf.test.entity,com.hjf.base,MyOgnl configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 是否開啟自動駝峰命名規則(camel case)映射,即從經典數據庫列名 A_COLUMN(下劃線命名) 到經典 Java 屬性名 aColumn(駝峰命名) 的類似映射 map-underscore-to-camel-case: false global-config: db-config: id-type: auto #開啟hystrix 熔斷 feign: hystrix: enabled: true client: config: default: connect-timeout: 4000 read-timeout: 4000 # --------------負載均衡器配置------------------ ribbon: ReadTimeout: 60000 ConnectTimeout: 60000 #阿里分布式事務配置 seata: service: tx-service-group: my_test_tx_group vgroup-mapping: #這里的組名my_test_tx_group就是上面已經配置過的 # seata-server 對應的就是register.conf里的application選項的內容 my_test_tx_group: seata-server grouplist: #這里對應的就是上面的seata-server,后面的蠶食seata服務的IP地址和端口號 seata-server: 127.0.0.1:8091 enable-degrade: false disable-global-transaction: false ~~~ ***** **2、配置數據源代理和掃描器** ~~~ @Configuration public class DataSourceProxyConfig { @Bean @ConfigurationProperties(prefix = "spring.datasource") public DataSource druidDataSource() { DruidDataSource druidDataSource = new DruidDataSource(); return druidDataSource; } } ~~~ **3、在需要開啟分布式事務的方法上加上@GlobalTransactional注解。** ~~~ 在TM開啟全局事務之后,TC返回一個XID,RootContext類中會保存XID,該XID是一個線程變量。 RM中根據XID向TC注冊分支變量。 ~~~ ***** ~~~ @GlobalTransactional(rollbackFor = Exception.class) public BaseResp addCarousel(MarketCarousel q) { marketCarouselMapper.insert(q); //遠程調用微服務添加數據 BaseResp r=feignService.add(q); if (StringUtils.isBlank(q.getTitle())){ //拋出異常事務回滾 throw new NullPointerException("拋出異常........"); } return BaseResp.SUCCESS; } ~~~ ***** **4、在業務系統和各個微服務中加入undo\_log表。** ***** ~~~ CREATE TABLE `undo_log` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `branch_id` bigint(20) NOT NULL, `xid` varchar(100) NOT NULL, `context` varchar(128) NOT NULL, `rollback_info` longblob NOT NULL, `log_status` int(11) NOT NULL, `log_created` datetime NOT NULL, `log_modified` datetime NOT NULL, `ext` varchar(100) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看