86 SpringCloud解決分布式事務(wù)

1茎活,分布式事務(wù)產(chǎn)生的背景;
分情況而定辖众。
1卓起,在單體項(xiàng)目中,多個(gè)不同的業(yè)務(wù)邏輯都是在同一個(gè)數(shù)據(jù)源中心實(shí)現(xiàn)事務(wù)管理凹炸,是不存在分布式事務(wù)的問題戏阅。因?yàn)樵谕粋€(gè)數(shù)據(jù)源的情況下都是采用事務(wù)管理器,相當(dāng)于每個(gè)事務(wù)管理器對(duì)應(yīng)一個(gè)數(shù)據(jù)源啤它。
2饲握,在單體項(xiàng)目中私杜,有多個(gè)不同的數(shù)據(jù)源,每個(gè)數(shù)據(jù)源中都有自己獨(dú)立的事務(wù)管理器救欧,互不影響,那么這時(shí)候也會(huì)存在多數(shù)據(jù)源事務(wù)管理:解決方案jta+Atomikos
3锣光,在分布式/微服務(wù)架構(gòu)中笆怠。每個(gè)服務(wù)都有自己的本地的事務(wù)。每個(gè)服務(wù)本地事務(wù)互不影響誊爹,那么這時(shí)候也會(huì)存在分布式事務(wù)的問題蹬刷。
分布式事務(wù)產(chǎn)生的背景:訂單服務(wù)調(diào)用派單服務(wù)接口成功之后,可能會(huì)引發(fā)錯(cuò)誤频丘。
2pc3pc思想办成,實(shí)際上都是解決我們?cè)诜植际较到y(tǒng)中,每個(gè)節(jié)點(diǎn)保證數(shù)據(jù)一致性問題搂漠。
事務(wù)的定義迂卢。
對(duì)我們業(yè)務(wù)邏輯可以實(shí)現(xiàn)提交或者是回滾,保證數(shù)據(jù)一致性的情況桐汤。所以而克,要么提交,要么回滾怔毛。
原子性a 要么提交 要么回滾员萍。
一致性 c
持久性d 事務(wù)一旦提交或者回滾后,不會(huì)再對(duì)該結(jié)果有任何的影響拣度。
Base 與 cap理論碎绎。
1,cap定律
這個(gè)定理的內(nèi)容是指的是在一個(gè)分布式系統(tǒng)中,Consistency(一致性)抗果,Availability(可用性)筋帖,Partition tolerance(分區(qū)容錯(cuò)性),二者不可兼容窖张。
1幕随,一致性(C)
在分布式系統(tǒng)中的所有數(shù)據(jù)備份,是在同一時(shí)刻是否同樣的值宿接,(等同于所有節(jié)點(diǎn)訪問同一份最新的數(shù)據(jù)副本)
2赘淮,可用性 A
在集群中一部分節(jié)點(diǎn)故障后,集群整體是否還能響應(yīng)客戶端的讀寫請(qǐng)求(對(duì)數(shù)據(jù)更新具有高可用性)

3睦霎,分區(qū)容錯(cuò)性(p) 形成腦裂問題:
以實(shí)際效果而言梢卸,分區(qū)相當(dāng)于對(duì)通信的時(shí)限要求,系統(tǒng)如果不能再時(shí)限內(nèi)達(dá)成數(shù)據(jù)一致性副女,就意味著發(fā)生了分區(qū)的情況蛤高,必須就當(dāng)前操作在C和A之間做出選擇。

4,總結(jié)下
以上可以知道分區(qū)容錯(cuò)性(P)主要代表網(wǎng)絡(luò)波動(dòng)產(chǎn)生的錯(cuò)誤戴陡,這是不可以避免的塞绿,且這三個(gè)模式不可以兼得,所以目前就2種模式: cp和Ap模式恤批。
其中cp表示遵循一致性的原則异吻,但不能保證高可用性,其中zookeeper作為注冊(cè)中心就是采用cp模式喜庞,因?yàn)閦ookeeper有過半節(jié)點(diǎn)不可以的話整個(gè)zookeeper將不可用诀浪。
AP表示遵循于可用性原則,例如Eureka作為注冊(cè)中心用的是AP模式延都,因?yàn)槠錇槿ブ行幕字恚捎媚阒杏形椅抑杏心愕南嗷プ?cè)方式,只要集群中有一個(gè)節(jié)點(diǎn)可以使用晰房,整個(gè)eureka服務(wù)就是可用的求摇,但可能會(huì)出現(xiàn)短暫的數(shù)據(jù)不一致問題。

Ap保證可用性:但是不能保證每個(gè)副本數(shù)據(jù)數(shù)據(jù)一致性嫉你,
cp保證數(shù)據(jù)一致性月帝;如果有過半的zk節(jié)點(diǎn)宕機(jī)的情況下,不能保證可用性幽污,但是必須保證每個(gè)副本節(jié)點(diǎn)之間數(shù)據(jù)一致性嚷辅,比如zk。

Base理論:
Base是 Basically Available(基本可用)距误,Softstate(軟狀態(tài))和Eventually consistent(最終一致性)三個(gè)短語的縮寫簸搞。Base理論是對(duì)CAP定理逐步演化而來的,base理論核心思想是:即使無法做到強(qiáng)一致性准潭,但每個(gè)應(yīng)用都可以根據(jù)自身業(yè)務(wù)特點(diǎn)趁俊,采用適當(dāng)?shù)姆绞竭_(dá)到最終一致性。
1基本可用性刑然;
基本可用是指分布式系統(tǒng)在出現(xiàn)不可預(yù)知故障的時(shí)候寺擂,允許損失部分可用性,注意:這絕不等于系統(tǒng)不可用泼掠。
比如: 響應(yīng)時(shí)間的損失怔软,正常情況下,在一個(gè)電子商務(wù)網(wǎng)站上進(jìn)行購物的時(shí)候择镇,消費(fèi)者幾乎能順利完成每一筆訂單挡逼,但是在一些介入大促銷購物高峰的時(shí)候,由于消費(fèi)者的購物行為激增腻豌,為了保護(hù)購物系統(tǒng)的穩(wěn)定性家坎,部分消費(fèi)者可能被引導(dǎo)在一個(gè)降級(jí)頁面嘱能。
2,軟狀態(tài)虱疏。
軟狀態(tài)指允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài)惹骂,并認(rèn)為該中間狀態(tài)的存在不會(huì)影響系統(tǒng)的整體可用性,既允許系統(tǒng)在不同節(jié)點(diǎn)的數(shù)據(jù)副本之間進(jìn)行數(shù)據(jù)同步的過程存在延時(shí)订框。

3析苫,最終一致性
最終一致性強(qiáng)調(diào)的是所有的數(shù)據(jù)副本,在經(jīng)過一段時(shí)間的同步之后穿扳,最終都能夠達(dá)到一個(gè)一致的狀態(tài),因此国旷,最終一致性的本質(zhì)需要系統(tǒng)保證數(shù)據(jù)能夠達(dá)成一致矛物,而不需要時(shí)時(shí)保證系統(tǒng)數(shù)據(jù)的強(qiáng)一致性。

2pc 與3pC
通過2pc和3pc 思想可以實(shí)現(xiàn)保證每個(gè)節(jié)點(diǎn)的數(shù)據(jù)一致性問題跪但。

目前主流分布式解決框架
1履羞,單體項(xiàng)目多數(shù)據(jù)源,可以jta+Atomilos屡久;
2忆首,基于Rabbitmq的形式解決 最終一致性思想;
3被环,基于Rocketmq解決分布式事務(wù) 糙及,采用事務(wù)消息。
4筛欢,lcn采用lcn模式浸锨,假關(guān)閉連接
5,Alibaba的seata 背景強(qiáng)大版姑,已經(jīng)成為了主流柱搜。
以上適合于微服務(wù)架構(gòu)中,不適合于和外部接口保證分布式事務(wù)問題剥险。
6聪蘸,跨語言的方式實(shí)現(xiàn)解決分布式事務(wù)問題。類似于支付寶回調(diào)方式表制。
2階段提交協(xié)議基本概念健爬。

2階段提交協(xié)議基本概念:

倆階段提交協(xié)議可以理解為2pc,也就是分為參與者和協(xié)調(diào)者夫凸,協(xié)調(diào)者會(huì)通過2次階段實(shí)現(xiàn)數(shù)據(jù)最終一致性的
2pc和3pc 的區(qū)別就是解決參與者超時(shí)問題和多加了一層詢問浑劳。保證了數(shù)據(jù)傳輸?shù)目煽啃浴?br> 簡單的回顧下lcn解決分布式事務(wù)。

http://www.txlcn.org/zh-cn/ LCN并不生產(chǎn)事務(wù)夭拌,LCN只是本地事務(wù)的協(xié)調(diào)工

現(xiàn)在官網(wǎng)已經(jīng)不維護(hù)呢魔熏,可以參考:GitEE

https://gitee.com/wangliang1991/tx-lcn?_from=gitee_search

默認(rèn)密碼為:codingapi

lcn基本實(shí)現(xiàn)的原理:
1衷咽,發(fā)起方與參與方都與我們的lcn保持長連接;
2蒜绽,發(fā)起方調(diào)用接口前镶骗,先向lcn管理器中申請(qǐng)一個(gè)全局的事務(wù)分組id;
3,發(fā)起方調(diào)用接口的時(shí)候在請(qǐng)求頭里傳遞事務(wù)分組id.
4,參與方獲取到請(qǐng)求頭中有事務(wù)分組的id的,則當(dāng)前業(yè)務(wù)邏輯執(zhí)行完實(shí)現(xiàn)假關(guān)閉躲雅,不會(huì)提交或者回滾當(dāng)前事務(wù)鼎姊,
5,發(fā)起方調(diào)用完接口后相赁,如果出現(xiàn)異常的情況下相寇,在通知事務(wù)協(xié)調(diào)者回滾事務(wù),這時(shí)候事務(wù)協(xié)調(diào)則告訴給參與者回滾當(dāng)前的事務(wù)钮科。

lcn 解決分布式事務(wù)的原理:
角色劃分
1唤衫,全局事務(wù)協(xié)調(diào)者(組長);
2绵脯,發(fā)起方---調(diào)用接口者佳励;
3,參與方---被別人調(diào)用接口
訂單(發(fā)起方)調(diào)用派單(參與方)
1.發(fā)起方和參與方都會(huì)與我們的全局事務(wù)協(xié)調(diào)者保持長連接蛆挫;

  1. 訂單(發(fā)起方)連接到我們?nèi)质聞?wù)協(xié)調(diào)者赃承,先生成一個(gè)事務(wù)全局的分組id
  2. 當(dāng)我們發(fā)起方調(diào)用接口的時(shí)候,會(huì)再請(qǐng)求頭中設(shè)置該事務(wù)全局分組id悴侵;
  3. 參與方從請(qǐng)求頭中獲取到該全局分組id瞧剖,這是我們的數(shù)據(jù)源就不會(huì)提交。
  4. 發(fā)起方調(diào)用參與方接口完畢之后畜挨,如果報(bào)錯(cuò)或者沒有問題的情況下筒繁,都會(huì)發(fā)送
    一個(gè)通知給事務(wù)協(xié)調(diào)者,通知給其他的參與方到底是回滾還是提交巴元。
    LCN實(shí)現(xiàn)分布式事務(wù)方案:有可能會(huì)引發(fā)行鎖問題毡咏。

整合和源碼解讀

spring-boot 2.1.6.RELEASE+spring-cloud Greenwich.RELEASE +seata 1.4
pom如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <groupId>com.taotao</groupId>
    <artifactId>consumer</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>consumer</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>

        <!-- Mysql驅(qū)動(dòng)包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.1.1</version>
        </dependency>

        <!--seata-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-seata</artifactId>
            <version>2.1.0.RELEASE</version>
            <exclusions>
                <exclusion>
                    <artifactId>seata-all</artifactId>
                    <groupId>io.seata</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-all</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>provider</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.taotao</groupId>
            <artifactId>provider</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>




file.conf



transport {
  # tcp udt unix-domain-socket
  type = "TCP"
  #NIO NATIVE
  server = "NIO"
  #enable heartbeat
  heartbeat = true
  # the client batch send request enable
  enableClientBatchSendRequest = false
  #thread factory for netty
  threadFactory {
    bossThreadPrefix = "NettyBoss"
    workerThreadPrefix = "NettyServerNIOWorker"
    serverExecutorThreadPrefix = "NettyServerBizHandler"
    shareBossWorker = false
    clientSelectorThreadPrefix = "NettyClientSelector"
    clientSelectorThreadSize = 1
    clientWorkerThreadPrefix = "NettyClientWorkerThread"
    # netty boss thread size,will not be used for UDT
    bossThreadSize = 1
    #auto default pin or 8
    workerThreadSize = "default"
  }
  shutdown {
    # when destroy server, wait seconds
    wait = 3
  }
  serialization = "seata"
  compressor = "none"
}
# service configuration, only used in client side
service {
  #transaction service group mapping
  vgroupMapping.my_test_tx_group = "default"
  #only support when registry.type=file, please don't set multiple addresses
  default.grouplist = "127.0.0.1:8091"
  #degrade, current not support
  enableDegrade = false
  #disable seata
  disableGlobalTransaction = false
}
#client transaction configuration, only used in client side
client {
  rm {
    asyncCommitBufferLimit = 10000
    lock {
      retryInterval = 10
      retryTimes = 30
      retryPolicyBranchRollbackOnConflict = true
    }
    reportRetryCount = 5
    tableMetaCheckEnable = false
    reportSuccessEnable = false
    sqlParserType = druid
  }
  tm {
    commitRetryCount = 5
    rollbackRetryCount = 5
  }
  undo {
    dataValidation = true
    logSerialization = "jackson"
    logTable = "undo_log"
  }
  log {
    exceptionRate = 100
  }
}

## transaction log store, only used in server side
store {
  ## store mode: file、db
  mode = "db"
  ## file store property
  file {
    ## store location dir
    dir = "sessionStore"
    # branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
    maxBranchSessionSize = 16384
    # globe session size , if exceeded throws exceptions
    maxGlobalSessionSize = 512
    # file buffer size , if exceeded allocate new buffer
    fileWriteBufferCacheSize = 16384
    # when recover batch read size
    sessionReloadReadSize = 100
    # async, sync
    flushDiskMode = async
  }

  ## database store property
  db {
    ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp) etc.
    datasource = "dbcp"
    ## mysql/oracle/h2/oceanbase etc.
    dbType = "mysql"
    driverClassName = "com.mysql.cj.jdbc.Driver"
    url = "jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8"
    user = "root"
    password = "root"
    minConn = 1
    maxConn = 10
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
  }
}
## server configuration, only used in server side
server {
  recovery {
    #schedule committing retry period in milliseconds
    committingRetryPeriod = 1000
    #schedule asyn committing retry period in milliseconds
    asynCommittingRetryPeriod = 1000
    #schedule rollbacking retry period in milliseconds
    rollbackingRetryPeriod = 1000
    #schedule timeout retry period in milliseconds
    timeoutRetryPeriod = 1000
  }
  undo {
    logSaveDays = 7
    #schedule delete expired undo_log in milliseconds
    logDeletePeriod = 86400000
  }
  #unit ms,s,m,h,d represents milliseconds, seconds, minutes, hours, days, default permanent
  maxCommitRetryTimeout = "-1"
  maxRollbackRetryTimeout = "-1"
  rollbackRetryTimeoutUnlockEnable = false
}

## metrics configuration, only used in server side
metrics {
  enabled = false
  registryType = "compact"
  # multi exporters use comma divided
  exporterList = "prometheus"
  exporterPrometheusPort = 9898
}

registry.conf:

registry {
  # file 逮刨、nacos 呕缭、eureka、redis修己、zk恢总、consul、etcd3睬愤、sofa
  type = "eureka"
  loadBalance = "RandomLoadBalance"
  loadBalanceVirtualNodes = 10

  nacos {
    application = "seata-server"
    serverAddr = "127.0.0.1:8848"
    group = "SEATA_GROUP"
    namespace = ""
    cluster = "default"
    username = ""
    password = ""
  }
  eureka {
    serviceUrl = "http://localhost:8761/eureka"
    application = "default"
    weight = "1"
  }
  redis {
    serverAddr = "localhost:6379"
    db = 0
    password = ""
    cluster = "default"
    timeout = 0
  }
  zk {
    cluster = "default"
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  consul {
    cluster = "default"
    serverAddr = "127.0.0.1:8500"
  }
  etcd3 {
    cluster = "default"
    serverAddr = "http://localhost:2379"
  }
  sofa {
    serverAddr = "127.0.0.1:9603"
    application = "default"
    region = "DEFAULT_ZONE"
    datacenter = "DefaultDataCenter"
    cluster = "default"
    group = "SEATA_GROUP"
    addressWaitTime = "3000"
  }
  file {
    name = "file.conf"
  }
}

config {
  # file片仿、nacos 、apollo尤辱、zk砂豌、consul厢岂、etcd3
  type = "file"

  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = ""
    group = "SEATA_GROUP"
    username = ""
    password = ""
  }
  consul {
    serverAddr = "127.0.0.1:8500"
  }
  apollo {
    appId = "seata-server"
    apolloMeta = "http://192.168.1.204:8801"
    namespace = "application"
    apolloAccesskeySecret = ""
  }
  zk {
    serverAddr = "127.0.0.1:2181"
    sessionTimeout = 6000
    connectTimeout = 2000
    username = ""
    password = ""
  }
  etcd3 {
    serverAddr = "http://localhost:2379"
  }
  file {
    name = "file.conf"
  }
}



yml配置:

server:
  port: 8002
##服務(wù)名稱(服務(wù)注冊(cè)到eureka名稱)
spring:
  main:
    allow-bean-definition-overriding: true
  cloud:
    alibaba:
      seata:
        tx-service-group: my_test_tx_group
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/test1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: root
    password: root
  application:
    name:  consumer
##服務(wù)注冊(cè)到eureka 地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
###因?yàn)樵搼?yīng)用為注冊(cè)中心,不會(huì)注冊(cè)自己
register-with-eurkea: true
###是否需要從eureka上獲取注冊(cè)信息
fetch-registry: true
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
  level:
    com.taotao.consumer.mapper: trace




添加 DataSourceConfiguration

package com.taotao.consumer;

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;


@Configuration
public class DataSourceConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        return druidDataSource;
    }

    @Primary
    @Bean("dataSource")
    public DataSourceProxy dataSource(DataSource druidDataSource){
        return new DataSourceProxy(druidDataSource);
    }


    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSourceProxy);
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:/mapper/*.xml"));
        sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
        return sqlSessionFactoryBean.getObject();
    }

}




package com.taotao.consumer;


import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;



@MapperScan("com.taotao.consumer.mapper")
@EnableEurekaClient
@EnableFeignClients
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class ConsumerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

}

image.png

其他模塊參照此模塊配置阳距,
seata的registry.conf 和file.conf配置和項(xiàng)目配置一致塔粒。
添加全局事務(wù):


 @GlobalTransactional
    @Override
    public int insertOnlineList(OnlineSheet onlineSheet) {
        onlineSheetFeign.insertOnlineSheet(onlineSheet);
        OnlineList onlineList = new OnlineList();
        onlineList.setPassword("123");
        onlineList.setList_id("1");
        onlineListMapper.insertOnlineList(onlineList);
        return 1 / Integer.parseInt(onlineSheet.getIndex());


    }

https://gitee.com/lttwj/wj1/tree/master/seata/springcloud-seata

1,如何學(xué)會(huì)分析框架的源碼?思想有哪些筐摘?
A: spring入口角度分析 springbean 生命周期ioc容器底層原理卒茬。
B. 報(bào)錯(cuò)日志法
2,seata 底層如何解決分布式事務(wù)的咖熟?
3圃酵,seata 如何生成全局xid
4,Seata如何生成前置和后置鏡像。
5馍管,seata 如何傳遞xid的
6辜昵, Seata 如何實(shí)現(xiàn)逆向回滾
7,如果協(xié)調(diào)者宕機(jī)了咽斧,參與事務(wù)是回滾還是提交
8,如果協(xié)調(diào)者宕機(jī)發(fā)起方?jīng)]有通知協(xié)調(diào)者到底是提交還是回滾躬存?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末张惹,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子岭洲,更是在濱河造成了極大的恐慌宛逗,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盾剩,死亡現(xiàn)場離奇詭異雷激,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)告私,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門屎暇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人驻粟,你說我怎么就攤上這事根悼。” “怎么了蜀撑?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵挤巡,是天一觀的道長。 經(jīng)常有香客問我酷麦,道長矿卑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任沃饶,我火速辦了婚禮母廷,結(jié)果婚禮上轻黑,老公的妹妹穿的比我還像新娘。我一直安慰自己徘意,他們只是感情好苔悦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著椎咧,像睡著了一般玖详。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上勤讽,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天蟋座,我揣著相機(jī)與錄音,去河邊找鬼脚牍。 笑死向臀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的诸狭。 我是一名探鬼主播券膀,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼驯遇!你這毒婦竟也來了芹彬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤叉庐,失蹤者是張志新(化名)和其女友劉穎舒帮,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體陡叠,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玩郊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了枉阵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片译红。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖岭妖,靈堂內(nèi)的尸體忽然破棺而出临庇,到底是詐尸還是另有隱情,我是刑警寧澤昵慌,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布假夺,位于F島的核電站,受9級(jí)特大地震影響斋攀,放射性物質(zhì)發(fā)生泄漏已卷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一淳蔼、第九天 我趴在偏房一處隱蔽的房頂上張望侧蘸。 院中可真熱鬧裁眯,春花似錦、人聲如沸讳癌。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晌坤。三九已至逢艘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間骤菠,已是汗流浹背它改。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留商乎,地道東北人央拖。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像鹉戚,于是被迫代替她去往敵國和親鲜戒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容