Back to Javatutorial

SpringCloudAlibabaSeata

docs/Spring全家桶/SpringCloudAlibaba/SpringCloudAlibabaSeata.md

1.0.024.2 KB
Original Source

Ƕ֪ Seata һֲʽĽǾ˽һʲôǷֲʽ˽һ»֪ʶ˽һĸʲô

IJֹɡ ACID

  • A(Atomic)ԭԣвҪôȫִгɹҪôȫִʧܣֲֳɹ߲ʧܵ
  • C(Consistency)һԣִǰݿһԼûбƻ磬Сȥȡ100Ǯȡ֮ǰ600ȡ֮Ӧ400ȡ֮ǰȡ֮ΪȷֵΪһԣȡ100Ǯûм٣ҪôСҪЦˣûдﵽһԵҪ
  • I(Isolation):ԣݿеһ㶼Dzģֻڲִй̻ţһִйвܿй̵м״̬ͨ뼶Աظ⡣
  • D(Durability)־ԣ֮ݵĸĻᱻ־ûݿ⣬Ҳع

Ϊ֣ͷֲʽ

ڼϵͳУȽ϶ͨϵݿݿⱾԽʵֵģΪӦҪϵݿά񣬼ݿӦöͬһԻڹϵݵֱΪ

ֲʽ

ֲʽָIJߡ֧ķԴԼ߷ֱλڲͬķֲʽϵͳIJͬڵ֮ϣڲͬӦãֲʽҪ֤ЩҪôȫɹҪôȫʧܣֲʽΪ˱֤ڲͬݿݵһԡ

Seata ˼·ǽıһȫɸ񣬶ACIDγһķֲʽ񣬲ֲʽDzһ

ֲʽϵͳһӦòΪɶķ񣬷ڷ֮ͨҪԶЭIJֲַʽϵͳڲͬķ֮ͨԶЭɵ񱻳Ϊֲʽ繩ӦϵͳУɶۼ桢Լ֪ͨȡ

ͼǿԿֻҪ漰Դͻ⣬ʵʿӦҪij֣ȻϵͳչӦúӦ֮ȻӦ֮ķ룬΢ܹУҪMQSeata˽֮ǰ˽һ·ֲʽɣԼʵֵġ

ֲʽ

ֲʽʲô

ֲʽָIJߣ֧ķԴֱλڷֲʽϵͳIJͬڵ֮ϣͨһֲʽл漰ԶԴҵϵͳIJ

Żķչ֮ǰĵһĿֲʽת΢ڸ˾ѾձڣʱıѾ޷ֲʽӦõҪ˷ֲʽ֮ЭͲ⣬֮IJܹ񱾵һѭACIDԭ򣬳Ϊһ⣬ڴţDzϵ̽£ҵ˷ֲʽݣCAPɺBASEۡ

CAP

CAPһ(C)(A)ݴ(P)ɣڷֲʽϵͳУͬʱConsistency(һ)/Availability()/Partition tolerance(ݴ) ԣֻͬʱ

  • һ(C)ڷֲʽϵͳеݱݣͬһʱ̱һµԣеӦýڵʵĶͬһµݸ
  • (A): ȺһֽڵԺ󣬼ȺܹӦͻ˵Ķд󣬶ݸ¾߱߿ԡ
  • ݴ(P): ϵͳڹ涨ʱڲܴݵһԣͱʾҪǰҪCA֮ѡϵͳܹϵʱȻܹ֤ṩһԻ߿Եķ

ͼǿԿûȥﳵµʱȻᾭǿжϿǷ㹻㣬ۼԺҪͬϣһΪ˱֤ݵĽһԣʱˣǵϵͳҪ֤ݴԣҲDZһЩ⣬ʱ뱣֤һԣҪԡ

Ϊ˱֤߿ԣôڸ߲£޷֤޶ʱڸӦIJɿǵĶ޷õµݣҪûӦôҲ޷֤һԣAP޷֤ǿһԵġ

Ҫ֤߿Ҫ֤һԣõ²ʵ֣ôֻһǾҪ桢Լŵһ𣬵ȥ΢ãҲͲǷֲʽϵͳˡ

ڷֲʽϵͳУݴDZڵģֻһԺͿȡᣬ¾͵BASEۡ

BASE

BASE (Basically Available)״̬ (Soft state) һ (Eventually consistent) ɣǶCAPһԺͿȨĽԴڶԻϵͳֲʽʵܽᣬǻCAPݻģϵǸǼʱ޷ǿһԣÿӦöԸҵص㣬ʵķʽʹϵͳﵽһԡ

  1. ãֲָʽϵͳֲԤ֪ϵʱʧֿԣﲢ˵ʾϵͳãҪΪ¼:
  • Ӧʱϵʧ£һҪ0.5֮ڷظûӦIJѯڳֹϣѯӦʱ1-2롣
  • ϵͳϵʧ£һվϽй߼ܹ˳ÿһһЩմ߷ڵʱվϹΪ˱֤ϵͳȶԣ߿ܻһʱҳʾ

õ˼ǣǵĺķǿʹõģķʵĽӦʱ䣬ǽз񽵼ڵǰУͶ϶ǺķǵķϵͳڵʱֻҪ֤þУͬһӳٸߣȴ߷ȥԺڽлָ

  1. ״̬״ָ̬ϵͳеݴм״̬Ϊм״̬ĴڲӰϵͳԣϵͳýڵݸ֮ͬĹ̴ʱ

״̬˼˵Ǵµʱ򣬿ۼʱʱʵ߶УܻὫϵͳŪ壬ǿݵͬӳ٣Ӱϵͳʹá

  1. һԣһǿݸھһʱ֮ͬնܹﵽһһµ״̬ˣһԵıҪϵͳ֤ܹﵽһ£Ҫʵʱ֤ϵͳǿһԡ

߷Ժ󣬾һʱͬм״̬һԣ֤ݵһԡ

׶ύ(2PC)

2PC׶ύЭ飬ǽ̷Ϊ׶ΣPָ׼׶ΣCָύ׶Ρ

ͺñȥKCCܳԣǸպлڶۣһˣʱպиСڿܳԣʱAAҲͻ˵ֻеͬʱ򣬲ܹ򵽣һͬôͲܳԡ

׶һ׼׶ ϰҪȽиͬ⸶ɺҪŮŮͬ⸶ɡ

׶ζύ׶ ɣϰͣ˶Եܡ

ӾһŮ˫һ˾ܾôϰͲͣһȡǮԭ·˻ء

ͲɵģϰǸŮDzߣֲʽڼйϵ֧׶ύЭ飺

  • ׼׶(Prepare phase)ÿ߷Prepare Ϣÿݿڱִ񣬲дصUndo/Redo ־ʱûύ

undo־Ǽ¼޸ǰݣݿع

Redo ־Ǽ¼޸ĺݣύдļ

  • ύ׶(commit phase)յ˲ߵִʧܻ߳ʱϢʱֱӸÿ߷(Rollback) Ϣյ߶ɹ(Commit) ߸ִָύ߻عͷʹõԴ

ɹύ

в߷ݣѯǷ׼ˣȴߵӦڵִ UndoRedo Ϣ־С߳ɹִYESʾִУЭߴеIJ߻÷YesӦôͻִύ

ʧܣ

κһNoָߵȴʱ֮޷յвߵķӦôж񣬷ͻعв߽ڵ㷢 RollBack 󣬲߽յ RollBack 󣬻ڽ׶һ¼UndoϢִĻعɻع֮ͷִڼռõԴع֮Э߷ACKϢڽܵв߷ACKϢ֮жϡ

׶ύ(3PC)

3PC ҪΪ˽׶ύЭĵСΧǶ׶ύ2PCĸĽ汾ڵijʱ֮⣬3PC2PC׼׶ηֳѯʣý׶βԤύ,׶ηֱΪ CanCommitPreCommitDoCommit

CanCommit ѯ״̬

CanCommit׶ Э(Coordinator)(Participant) CanCommitϢѯǷִвյϢ󣬱ʾִܹУ᷵ظЭִܹе(yes)

ִ߲У᷵No,ͷԴ

PreCommit Ԥύ

PreCommit ׶Эյ߷ص״ֵ̬ΪYESô֤ǶȥִôЭ߾ͻв PreCommit ϢЭյ PreCommitϢ󣬻ȥִбִгɹὫ񱣴浽 undoredo ٷظЭYESָִбʧܣЭNo,ֻҪЭյһִʧܣв߷жϢյϢ󣬶лع

׶βߺЭ߶˳ʱƣûյЭߵϢЭûյ߷صԤִн״̬ڵȴʱ֮жϣ

Э߷PreCommitִгɹyes

ִʧܣֻһNoЭߣЭ߻߷жϢ߻ع

DoCommit ύ

Эյв߷ص״̬YESʱЭ߻еIJ߶ DoCommit յ DoCommit 󣬻ύ񣬵ύɹ󣬷ЭYES״̬ʾѾύˣЭյв߶YES״̬ô˱

ij߷NoϢЭ߷жϢ(abort)ǣ߻ع

3PC2PC棬˳ʱƣ˵⣬3PCȻܽһԵ⣬ΪDoCommit׶Σ߳ʱԭ²ղЭ߷͹ жϢ(abort) ʱ󣬲߻ύ񣬱Ӧýлعύ󣬻ᵼݲһµ֣2PCȻ´ǿһԱƻ⣬ǹϻָԺܱ֤һԣ3PCȻгʱʱ䣬˿ԣһԣ粨⵼һϣ2PC3PCġ

Seata

https://seata.io/zh-cn/docs/overview/what-is-seata.html

Seata һԴķֲʽṩܺͼõķֲʽSeata Ϊûṩ ATTCCSAGA XA ģʽΪûһվʽķֲʽ

΢ϵͳУһҵᱻֳɶģ飬ڹٷṩĽṹͼУǿԿǰҪΪģ顣

  • 񣺶ƷϢӻ߼ٲ
  • 񣺸ûָƷɶ
  • ˻񣺴û˻п۳ӻ֣άַϢȵȡ

ڵǰܹУûѡǵƷµҪɲÿһڲӵһı֤ǰݵǿһԣɵȫһԾû취б֤ôSeataġ

Seata

ַhttps://seata.io/zh-cn/docs/overview/terminology.html

˽Seata֮ǰ˽һ Seata ؼĸ

  1. TC(Transaction Coordinator)Эߣάȫֺͷ֧״̬ȫύ߻ع
  2. TM(Transaction Manager) ߣ ߣͬʱһRMһ֣ȫķΧʼȫύعȫ
  3. RM(Resource Manager) Դ ΢񣬹֧ԴTC̸ע֧ͱ֧״̬֧ύع

Seata 2PC

һ׶Σ ҵݺͻع־¼ͬһύͷűԴ

׶Σ ύ첽dzٵɡعͨһ׶εĻع־з򲹳

һ׶αύǰҪȷõ ȫ òȫ ύȫijԱһΧڣΧعͷű

ݿⱾ뼶ύϵĻϣSeataAT ģʽĬȫָ뼶 δύ

Ӧض£Ҫȫֵ ύ Ŀǰ Seata ķʽͨ SELECT FOR UPDATE Ĵ

Seata̷ִ

ÿRM ʹ DataSourceProxy ·Ŀʹ ConnectionProxy ʹԴݴĿڵһ׶ν undoҵݷһύͱֻҪҵһdudo־

ڵһ׶Уundo޸ǰ޸ĵֵΪع׼ڵһ׶ɾѾ֧ύˣҲͷԴ

TMȫʼXIDȫIDУͨfeignýXIDηУÿ֧Լ Branch ID֧IDXIDй

ڵڶ׶ȫύTC֪֧ͨύ֧ڵһ׶Ѿύ˷ֻ֧Ҫɾundoɣҿ첽ִС

ijһ֧쳣ˣڶ׶ȫعTC֪֧ͨ߻ع֧ͨXIDBranch-IDҵӦĻع־ͨع־ɵķSQLִУɷ֧ع֮ǰ״̬

Seata ذװ

صַhttps://github.com/seata/seata/releases

ѹҵconfĿ¼

seata֮ǰҪnacosʵҲܼ򵥣ֻҪnacosУ֪nacosôĿĽnacosܣ֮seatabinĿ¼seata-server.bat

ǿ8091˿ڼnacosעȥˣͱʾseataɹˡ

ܽ

ǹڷֲʽĺseataĽܾͽˣʵڷֲʽMQʵֿɿϢһԣMQҪܣϢ͵ԭ⡣뷽ϢĿɿԡ

ǰ

һǽˣڷֲʽseataĻܺʹãȤСԻعһ˵㲻ֲ֪ʽ! СũҲ˵ˣڻҹSeataйseataATTCCSAGA XA ģʽĽܺʹãSeataзֲʽģ͵Ľܡ

SeataΪģ飬ֱ TMRM TC

TC (Transaction Coordinator) - Эߣάȫֺͷ֧״̬ȫύع

**TM (Transaction Manager) - **ȫķΧʼȫύعȫ

RM (Resource Manager) - Դ֧ԴTC̸ע֧ͱ֧״̬֧ύع

Seata Уֲʽִ̣

  • TM ֲʽTM TC עȫ¼
  • ҵ񳡾ݿ⡢ԴRM TC 㱨Դ׼״̬
  • TM ֲʽһ׶νTM ֪ͨ TC ύ/عֲʽ񣩡
  • TC Ϣֲʽύǻع
  • TC ֪ͨ RM ύ/ع Դ׶ν

TM RM Ϊ Seata ĿͻҵϵͳһTC Ϊ Seata ķ˶

˴洢ģʽ֧֣

file ģʽȫỰϢڴжд־ûļroot.dataܽϸߣĬϣ

DB: ߿ģʽȫỰϢͨDBܲһЩ

redis Seata-Server1.3ϰ汾֧֣ܽϸߣϢʧգҪʵʳʹá

TC

ʹDB߿ģʽҵconf/file.confļ

޸еϢҵӦdbã޸еjdbcӣҪע漰global_tablebranch_tablelock_tableͬʱ mysql5mysql8Dzһġ

mysql5com.mysql.jdbc.Driver

mysql8com.mysql.cj.jdbc.Driver

ַhttps://github.com/seata/seata/blob/develop/script/server/db/mysql.sql

global_table ȫÿһȫ󣬾ͻڸñм¼ȫID

branch_table ֧¼ÿһ֧ ID֧ĸݿϢ

lock_table ȫ

úԺSeataЧ

Seata Nacos

Seata֧עNacosԼ֧Seata÷ŵNacosģNacosͳһά ߿ģʽ¾ҪNacos

ҵ conf/registry.conf޸registryϢ

registry {
  # file nacos eurekarediszkconsuletcd3sofa
  type = "nacos"
  nacos {
    application = "seata-server" # ҪͿͻ˱һ
    serverAddr = "127.0.0.1:8848"
    group = "SEATA_GROUP"  # ҪͿͻ˱һ
    namespace = ""
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
  config {
  # filenacos apollozkconsuletcd3
  type = "nacos"
  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = ""
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos"
    dataId = "seataServer.properties"
  }
  ......
}

޸ĺú󣬽seataеһЩϴNacosУΪȽ϶࣬Թٷṩһconfig.txtֻز޸ijЩϴNacosмɡ

صַhttps://github.com/seata/seata/tree/develop/script/config-center

޸£

service.vgroupMapping.mygroup=default # 
store.mode=db
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
store.db.user=root
store.db.password=123456

޸ĺļԺ󣬰ļŵseataĿ¼£

Щö뵽NacosУҪһűִУٷѾṩá

ַΪhttps://github.com/seata/seata/blob/develop/script/config-center/nacos/nacos-config.sh

½һnacos-config.shļűݸƽȥ޸congfig.txt·

ļ޸ĺú󣬴gitߣnacos-config.shקмɻʹ

sh nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP -t 88b8f583-43f9-4272-bd46-78a9f89c56e8 -u nacos -w nacos

-hnacosַ

-p˿ڣĬ8848

-gseataķбơ

-tnacosռid

-u-wnacosû롣

ĸִʧܣΪredisĹϵԺԣӰʹáԿNacosкܶ˵ɹseataɹ8091˿ڣʾǰùѾ׼ɡ

Seataģʽ

Seata ȫĿܣҪΪ¼

  1. TM TC (Begin)ύ(Commit)ع(Rollback)ȫ
  2. TMѴȫXID󶨵֧ϡ
  3. RMTCעᣬѷ֧XIDȫС
  4. RMѷִ֧нϱTC
  5. TCͷ֧ύBranch Commit֧عBranch RollbackRM

Seata ȫ ̣Ϊ׶Σ

  • ִн׶ ִз֧񣬲ִ֤н_ɻعģRollbackable__־ûģDurable_
  • ɽ׶Σ ִн׶ γɵľ飬Ӧͨ TM ȫύع TCTC RM ֧ Commit Rollback

Seata νģʽָ Seata ȫµ ֧ Ϊģʽ׼ȷؽӦý ֧ģʽ

ͬ ģʽ ֧ ʹòͬķʽﵽȫ׶εĿꡣش⣺

  • ִн׶ ִв ֤ ִн_ɻعģRollbackable__־ûģDurable_
  • ɽ׶Σյ TC ֧ύع

ATģʽΪ

  • ִн׶Σ

  • ɻع SQL ¼ع־

  • ־ûع־ҵ SQL ͬһύݿ

  • ɽ׶Σ

  • ֧ύ첽ɾع־¼

  • ֧عݻع־з򲹳

ͽͷϷSeataĴģʽĽܡ

Seata-XAģʽ

Seata 1.2.0 汾µģͣXAģʽʵ˶XAЭ֧֡XAģʽҪȥ

  • XAģʽʲô
  • Ϊʲô֧XA
  • XAģʽʵֺʹá

XAģʽ

Ҫ֪XAģʲôXA 淶 90 ͱڽֲʽ⣬ҲķֲʽΪҪݿڲҲ֧XAģʽģMYSQLXAģʽǿһԵص㣬ݿռʱȽϳܱȽϵ͡

XAģʽ׶ύ

  1. һ׶νעᣬעᵽTCУִSQL䡣
  2. ڶ׶TCж֪ͨύع
  3. ڵһڶ׶ιУһֱռݿܱȽϵͣҪôһύҪôһعʵǿһԡ

ATģʽTCCSAGAЩģʽԴXA淶ijЩҵ񳡾޷㡣

ʲôXAЭ

XA淶X/OPEN֯ķֲʽDTPDistributed Transaction Processing׼XA淶ȫ;ֲԴ֮ĽӿڣXA淶ĿԴ(ݿ⣬Ӧ÷Ϣеȣͬһзʣʹ ACID ԿԽӦóЧ

XA 淶 ʹ׶ύ2PCTwo-Phase Commit֤ԴͬʱύعκضΪXA淶类ԼеݿⶼжXA淶֧֡

ֲʽDTPģͶĽɫ£

  • APӦó򣬿ΪʹDTPֲʽij綩񡢿
  • RMԴΪIJߣһָһݿʵMySqlͨԴԸݿпƣԴŷ֧
  • TMЭ͹ȫ񣬹ʵڣЭRMȫֲָʽУҪݿ⹲ͬһһȫ

DTPģʽTMRM֮ͨѶĽӿڹ淶XAΪݿṩ2PCӿЭ飬ݿXAЭʵֵ2PCֳΪXA

Ӧó(AP)жͿ⣬Ӧó(AP)ͨTM֪ͨ(RM)Ϳ(RM)пۼɶʱRMûύ񣬶Դ

TMյִϢһRMִʧܣֱRMҲͻع񣬻عϣͷԴ

TMյִϢRMȫɹRMύύϣͷԴ

ֲʽͨЭXA淶ִʾ

һAPRM1,RM2JDBCӡ

ڶAP֪ͨȫIDRM1RM2עᵽȫID

ִж׶Эеĵһ׶prepare

IJprepare󣬾ύع

ǶXAԣһȫԴʧˣôζTMղ֧ôݣһֱӶҲSeataҪص⡣

SeataķֲʽܹУԴ(ݾ֡Ϣ)ȶXAЭ֧֣XAЭĻ֧

  • ִн׶Σ

  • ɻعҵSQLXA֧нУԴXAЭ֧֤ɻع

  • ־ûZA֧Ժִ XA prepareͬԴXAЭ֧֤־û

  • ɽ׶Σ

XAڵ

  • ֧ύִXA֧commit
  • ֧عִXA֧rollback

Seata Ѿ֧ģʽAT\TCC\SAGADz񣬲ƹ Դ ֮(Ҫôм棬ҪôӦò)Դڷֲʽ޸֪ģֶڷֲʽ޸֪һԵ⣬޷ȫһԡ

һ¼ڲУ80ۼΪ60ʱֿԱѯݽ60֮Ϊ쳣ععԭ80ôʱԱ60ʵݣм״̬Dzڵݡ

ͲͬXAЭҪԴ ṩԹ淶Э֧֣ΪԴֲ֪ʽУԴԱ֤ӽǶݵķЧԣȫݵһԡ

XAģʽʹ

ٷhttps://github.com/seata/seata-samples

Ŀseata-samples

ҵʼbusiness-xastock-xaorder-xa˺ŷaccount-xa

ĿԺҵĿΪseata-xaĿ¼вݿӣòݿ⣬ֻҪ޸ĹٷĵݿϢɡ

ȹע business-xaĿĹעBusinessService.purchase()

@GlobalTransactional
    public void purchase(String userId, String commodityCode, int orderCount, boolean rollback) {
        String xid = RootContext.getXID();
        LOGGER.info("New Transaction Begins: " + xid);       
        //ÿ
        String result = stockFeignClient.deduct(commodityCode, orderCount);
        if (!SUCCESS.equals(result)) {
            throw new RuntimeException("ʧ,ع!");
        }
        //ɶ
        result = orderFeignClient.create(userId, commodityCode, orderCount);
        if (!SUCCESS.equals(result)) {
            throw new RuntimeException("ʧ,ع!");
        }
        if (rollback) {
            throw new RuntimeException("Force rollback ... ");
        }
    }

ʵַ֮ǰֻ࣬Ҫorder-xa(OrderService.create)Ϊ(int i = 1/0;)

public void create(String userId, String commodityCode, Integer count) {
        String xid = RootContext.getXID();
        LOGGER.info("create order in transaction: " + xid);
        int i = 1/0;
        // ܼ = (count) * Ʒ(100)
        int orderMoney = count * 100;
        // ɶ
        jdbcTemplate.update("insert order_tbl(user_id,commodity_code,count,money) values(?,?,?,?)",
            new Object[] {userId, commodityCode, count, orderMoney});
        // ˻ۼ
        String result = accountFeignClient.reduce(userId, orderMoney);
        if (!SUCCESS.equals(result)) {
            throw new RuntimeException("Failed to call Account Service. ");
        }

    }

һԽXAģʽATģʽתOrderXADataSourceConfiguration.dataSource

@Bean("dataSourceProxy")
    public DataSource dataSource(DruidDataSource druidDataSource) {
        // DataSourceProxy for AT mode
        // return new DataSourceProxy(druidDataSource);
        // DataSourceProxyXA for XA mode
        return new DataSourceProxyXA(druidDataSource);
    }

ĸ񣬷ʵַ http://localhost:8084/purchase

ǿбȻȥӦݿݣûзģ˵ǵXAģʽЧˣdubugȥĿʱ򣬵ݸĵʱݿʵҲûм¼ģΪXAǿһԣֻеԺ󣬲Żеݡ

XAģʽļ룬SeataȫһԳµȱڣγATTCCSagaXA Ĵģʽİͼгֲʽ

XAATҵģTCCSagaһҵġ

Seata-ATģʽ

һATģʽATģʽһûķֲʽĽATģʽ£ûֻעԼҵSQLûҵSQLΪһ׶ΣSeataܻԶж׶ύͻع

׶ύЭݱ䣺

  • һ׶Σҵݺͻع־¼ͬһύͷűԴ
  • ׶Σ ύ첽dzٵɡ عͨһ׶εĻع־з򲹳

ATģʽҪص

  1. һԡ
  2. ܽXAߡ
  3. ֻڵһ׶λȡڵһ׶νύͷ

һ׶УSeata ҵSQL ȽSQL壬ҵҪҵݣݱǰ¼ undo logȻִ ҵSQL ݣ֮ٴα redo logЩڱݿɣ֤һ׶εԭԡ

һ׶Σ׶αȽϼ򵥣Ļعύ֮ǰһ׶бûͨôִȫֻعִȫύعõľһ׶μ¼ undo Log ͨع¼ɷSQLִУɷ֧ĻعȻɺͷԴɾ־

AT̷Ϊ׶ΣҪ߼ȫڵһ׶Σڶ׶Ҫع־Ĺ£

ͼǿԿTMTC뿪һȫһͨ@GlobalTransactionalעTC᷵һȫID(XID)ִб֮ǰRMTCעһ֧ undo log ִбredo log ύTC㱨ִOK

Զ̵ãIDݸ񣬿ִб֮ǰTCע֧񣬿ͬundo Logredo LogTC㱨״̬ɹ

ȫύTC֪ͨRMһundoredo־һִʧܣôعͨundo logлع

ﻹһ⣬Ϊÿӱύ֪ͨعʱ棬Ѿ޸ģֱundo logлعܻᵼݲһµ

ʱ RM redo log֤ԱǷһӶ֪Ƿб޸Ĺundo logڱ޸ǰݣعredologڱ޸ĺݣڻعУ顣

ûб޸ĹֱӽлعݣredologУд

ʵս

˽ATģ͵Ļʵսһ£ATģ;ʵֵġ cloud-alibaba-seata-order cloud-alibaba-seata-stock

ṹt_ordert_stockundo_logűĿԴͱṹundo_log˱ݵĻعĩӡ

cloud-alibaba-seata-orderĴ£

controller

@RestController
public class OrderController {
    @Autowired
    private OrderService orderService;
    @GetMapping("order/create")
    @GlobalTransactional //ֲʽ
    public String create(){
        orderService.create();
        return "ɹ";
    }
}

OrderService

public interface OrderService {
    void create();
}

StockClient

@FeignClient(value = "seata-stock")
public interface StockClient {
    @GetMapping("/stock/reduce")
    String reduce();

}

OrderServiceImpl

@Service
public class OrderServiceImpl implements OrderService{
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private StockClient stockClient;
    @Override
    public void create() {
        //ۼ
        stockClient.reduce();
        System.out.println("ۼɹ");
        //ֹ쳣 ڻعϢ
        int i = 1/0;
        System.err.println("쳣");
        //
        orderMapper.createOrder();
        System.out.println("ɹ");
    }
}

OrderMapper

@Mapper
public interface OrderMapper {
    @Insert("insert into t_order (order_no,order_num) value (order_no+1,1)")
    void createOrder();
}

cloud-alibaba-seata-stockĴ£

@RestController
public class StockController {
    @Autowired
    private StockService stockService;
    @GetMapping("stock/reduce")
    public String reduce(){
        stockService.reduce();
        return "ѿۼ"+ new Date();
    }
}
public interface StockService {
    void reduce();
}
@Service
public class StockServiceImpl implements StockService{
    @Autowired
    StockMapper stockMapper;
    @Override
    public void reduce() {
        stockMapper.reduce();
    }
}
@Mapper
@Repository
public interface StockMapper {
    @Update("update t_stock set order_num = order_num - 1 where order_no = 1 ")
    void reduce();

}

붼Ƚϼ򵥣ǾͲעҲУҪorderstock֮ǰǵNacosSeataҪʱǷorderRestӿڣhttp://localhost:8087/order/create,Ϊ֤undo_logıڴ洢عݣOrderServiceImpl.create()Ӷϵ㣬debugķʽ

Ȼhttp://localhost:8087/order/createڵʱ䣬ȥundo_logͿ֣ᷢȷʵˣundo_logҲ˶ӦĿռ¼޸ĵǰϢݾعݡ

ǵF9ͨԺ󣬿ָundo_logҲûˣʱ֤ǵSeataЧعɹ

Ǿ֤ATִй̣XATCCģͣSeataATģͿӦԴҵ񳡾ҿҵ룬޸֪Эύ߻عͨAOPɣֻҪעҵ񼴿ɡ

SeataҪڲͬķ֮䴫ȫΨһIDDubboȿܼɻȽѺãDubboùʿIDĴݣIDĴ̶ԿҲ޸֪

Seata-TCCģʽ

ʹðhttps://seata.io/zh-cn/blog/integrate-seata-tcc-mode-with-spring-cloud.html

ʲôTCC

TCC ǷֲʽеĶ׶ύЭ飬ȫΪ Try-Confirm-CancelԴԤTryȷϲConfirmȡCancelǵľ庬£

  1. TryҵԴļ鲢Ԥ
  2. Confirmҵύ commit ֻҪ Try ɹôòһɹ
  3. Cancelҵȡعòض Try ԤԴͷš

TCC һʽķֲʽҪҵϵͳʵ֣ҵϵͳŷdzԣԸӣŵ TCC ȫݿ⣬ܹʵֿݿ⡢ӦԴЩͬݷͨʽı뷽ʽʵһԭӲõؽڸָҵ񳡾µķֲʽ⡣

TCCAT

AT ģʽ ֱ֧ ACID ϵݿ⣺

  • һ׶ prepare ΪڱУһύҵݸºӦع־¼
  • ׶ commit ΪϳɹԶ첽ع־
  • ׶ rollback Ϊͨع־Զɲݻع

ӦģTCC ģʽڵײԴ֧֣

  • һ׶ prepare ΪԶ prepare ߼
  • ׶ commit ΪԶ commit ߼
  • ׶ rollback ΪԶ rollback ߼

ν TCC ģʽְָ֧ Զ ķ֧뵽ȫĹС

ص㣺

  1. ԱȽǿҪԼʵ߼
  2. ̻ûܽǿ

Seata-Sagaģʽ

SagaģʽSEATAṩijSagaģʽУҵÿ߶ύ񣬵ijһʧ򲹳ǰѾɹIJߣһ׶Ͷ׶βִдʱˣһ޸Ļᣩҵ񿪷ʵ֡

Saga ģʽ·ֲʽͨ¼ģ֮첽ִеģSaga ģʽһֳ

֮ǰѧϰSeataֲʽֲģʹõĵ΢ȫԸݿߵ޸ģһЩ⻷£ϵͳյϵͳ޷޸ģͬʱûκηֲʽ룩ôATXATCCģͽȫʹãΪ˽⣬Sagaģ͡

磺߿˾ķϵͳ޷죬ʹSagaģʽ

SagaģʽSeataṩijṩ칹ϵͳͳһģ͡SagaģʽУеҵ񶼲ֱӲĴֻ𱾵Ĵȫյöʵ֣ڽҵ߼ʱijһҵʱԶȫѾɹߣһ׶εúͶ׶εķ񲹳ȫҵ񿪷ʵ֡

Saga״̬

ĿǰSeataṩSagaģʽֻͨ״̬ʵ֣ҪֹĽSagaҵ̻ƣҽתΪJsonļڳʱļʵҵԼ񲹳ҪSaga״̬ͼĻƣһҪͨSaga״̬ʵ֡

ԭ

  • ͨ״̬ͼõ̲jsonļ
  • ״̬ͼһڵԵһ񣬽ڵIJڵ㡣
  • ״̬ͼ json ״ִ̬У쳣ʱ״̬淴ִѳɹڵӦIJڵ㽫ع
  • ʵֵַ֧ѡ񡢲̡תӳ䡢ִ״̬жϡ쳣ȹܡ

Saga״̬Ӧ

ٷĵַhttps://seata.io/zh-cn/docs/user/saga.html

Seata Safa״̬ӻͼʹõַhttps://github.com/seata/seata/blob/develop/saga/seata-saga-statemachine-designer/README.zh-CN.md

ܽ

ܵ˵SeataATģʽٷ֮80ķֲʽҵATģʽʵֵһԣԿܴм״̬XAģʽʵֵǿһԣЧʽϵһ㣬Saga֮ͬķֲʽԹڷֲʽĴģͣеҵ񳡾XAATûҵԣSagaTCCһҵ롣

ο

https://www.51cto.com/article/713007.html https://lijunyi.xyz/docs/SpringCloud/SpringCloud.html#_2-2-x-%E5%88%86%E6%94%AF https://mp.weixin.qq.com/s/2jeovmj77O9Ux96v3A0NtA https://juejin.cn/post/6931922457741770760 https://github.com/D2C-Cai/herring http://c.biancheng.net/springcloud