小言_互联网的博客

Spring Cloud Alibaba--seata微服务详解之分布式事务(三)

324人阅读  评论(0)

        上篇讲述gateway的部署和使用,gateway统一管理和转发了HTTP请求,在互联网中大型项目一定存在复杂的业务关系,尤其在商城类软件中如淘宝、PDD等商城,尤其在秒杀场景中,并发量可以到达千万级别,此时数据库就会显得很无力。

        以Mysql为例,熟悉数据库的童鞋都知道数据库有原子性、隔离性、一致性、持久性四大特性,隔离级别分为脏读、幻读、可重复读、序列化四种。Mysql默认的隔离级别在可重复读,在高并发中显然会出现大量可重复度数据,分布式数据库显然是最适合的解决方案 。

1、Seata介绍

        Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

模式
TC  - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM - 事务管理器 RM (Resource Manager) - 资源管理器
RM  - 资源管理器 管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

2、Seata服务部署

        官网链接:http://seata.io/zh-cn/

        seata数据库脚本:https://github.com/seata/seata/blob/1.5.2/script/server/db/mysql.sql

        seata配置文件:https://github.com/seata/seata/blob/1.5.2/script/config-center/config.txt

        下载seata的压缩包,并且解压,在seata/script/server/db/下找到sql脚本

        在mysql中创建名为seata的数据库,并执行脚本:


  
  1. -- -------------------------------- The script used when storeMode is 'db' --------------------------------
  2. -- the table to store GlobalSession data
  3. CREATE TABLE IF NOT EXISTS ` global_ table`
  4. (
  5. `xid` VARCHAR( 128) NOT NULL,
  6. `transaction_id` BIGINT,
  7. ` status` TINYINT NOT NULL,
  8. `application_id` VARCHAR( 32),
  9. `transaction_service_ group` VARCHAR( 32),
  10. `transaction_name` VARCHAR( 128),
  11. `timeout` INT,
  12. `begin_ time` BIGINT,
  13. `application_ data` VARCHAR( 2000),
  14. `gmt_create` DATETIME,
  15. `gmt_modified` DATETIME,
  16. PRIMARY KEY (`xid`),
  17. KEY `idx_ status_gmt_modified` (` status` , `gmt_modified`),
  18. KEY `idx_transaction_id` (`transaction_id`)
  19. ) ENGINE = InnoDB
  20. DEFAULT CHARSET = utf 8mb 4;
  21. -- the table to store BranchSession data
  22. CREATE TABLE IF NOT EXISTS `branch_ table`
  23. (
  24. `branch_id` BIGINT NOT NULL,
  25. `xid` VARCHAR( 128) NOT NULL,
  26. `transaction_id` BIGINT,
  27. `resource_ group_id` VARCHAR( 32),
  28. `resource_id` VARCHAR( 256),
  29. `branch_ type` VARCHAR( 8),
  30. ` status` TINYINT,
  31. `client_id` VARCHAR( 64),
  32. `application_ data` VARCHAR( 2000),
  33. `gmt_create` DATETIME( 6),
  34. `gmt_modified` DATETIME( 6),
  35. PRIMARY KEY (`branch_id`),
  36. KEY `idx_xid` (`xid`)
  37. ) ENGINE = InnoDB
  38. DEFAULT CHARSET = utf 8mb 4;
  39. -- the table to store lock data
  40. CREATE TABLE IF NOT EXISTS ` lock_ table`
  41. (
  42. `row_ key` VARCHAR( 128) NOT NULL,
  43. `xid` VARCHAR( 128),
  44. `transaction_id` BIGINT,
  45. `branch_id` BIGINT NOT NULL,
  46. `resource_id` VARCHAR( 256),
  47. ` table_name` VARCHAR( 32),
  48. `pk` VARCHAR( 36),
  49. ` status` TINYINT NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
  50. `gmt_create` DATETIME,
  51. `gmt_modified` DATETIME,
  52. PRIMARY KEY (`row_ key`),
  53. KEY `idx_ status` (` status`),
  54. KEY `idx_branch_id` (`branch_id`),
  55. KEY `idx_xid_ and_branch_id` (`xid` , `branch_id`)
  56. ) ENGINE = InnoDB
  57. DEFAULT CHARSET = utf 8mb 4;
  58. CREATE TABLE IF NOT EXISTS `distributed_ lock`
  59. (
  60. ` lock_ key` CHAR( 20) NOT NULL,
  61. ` lock_ value` VARCHAR( 20) NOT NULL,
  62. `expire` BIGINT,
  63. primary key (` lock_ key`)
  64. ) ENGINE = InnoDB
  65. DEFAULT CHARSET = utf 8mb 4;
  66. INSERT INTO `distributed_ lock` ( lock_ key, lock_ value, expire) VALUES ( 'AsyncCommitting', ' ', 0);
  67. INSERT INTO `distributed_ lock` ( lock_ key, lock_ value, expire) VALUES ( 'RetryCommitting', ' ', 0);
  68. INSERT INTO `distributed_ lock` ( lock_ key, lock_ value, expire) VALUES ( 'RetryRollbacking', ' ', 0);
  69. INSERT INTO `distributed_ lock` ( lock_ key, lock_ value, expire) VALUES ( 'TxTimeoutCheck', ' ', 0);

        在seata/script/config-center/下找到config.txt 配置文件。

        seata需要集成到微服务中去,所以配置文件我们依然使用nacos管理。


  
  1. # For details about configuration items, see https: / /seata.io /zh-cn /docs /user /configurations.html
  2. #Transport configuration, for client and server
  3. transport. type =TCP
  4. transport.server =NIO
  5. transport.heartbeat = true
  6. transport.enableTmClientBatchSendRequest = false
  7. transport.enableRmClientBatchSendRequest = true
  8. transport.enableTcServerBatchSendResponse = false
  9. transport.rpcRmRequestTimeout = 30000
  10. transport.rpcTmRequestTimeout = 30000
  11. transport.rpcTcRequestTimeout = 30000
  12. transport.threadFactory.bossThreadPrefix =NettyBoss
  13. transport.threadFactory.workerThreadPrefix =NettyServerNIOWorker
  14. transport.threadFactory.serverExecutorThreadPrefix =NettyServerBizHandler
  15. transport.threadFactory.shareBossWorker = false
  16. transport.threadFactory.clientSelectorThreadPrefix =NettyClientSelector
  17. transport.threadFactory.clientSelectorThreadSize = 1
  18. transport.threadFactory.clientWorkerThreadPrefix =NettyClientWorkerThread
  19. transport.threadFactory.bossThreadSize = 1
  20. transport.threadFactory.workerThreadSize = default
  21. transport.shutdown.wait = 3
  22. transport.serialization =seata
  23. transport.compressor =none
  24. #Transaction routing rules configuration, only for the client
  25. service.vgroupMapping. default_tx_ group = default
  26. # If you use a registry, you can ignore it
  27. service. default.grouplist = 127.0.0.1: 8091
  28. service.enableDegrade = false
  29. service.disableGlobalTransaction = false
  30. #Transaction rule configuration, only for the client
  31. client.rm.asyncCommitBufferLimit = 10000
  32. client.rm. lock.retryInterval = 10
  33. client.rm. lock.retryTimes = 30
  34. client.rm. lock.retryPolicyBranchRollbackOnConflict = true
  35. client.rm.reportRetryCount = 5
  36. client.rm.tableMetaCheckEnable = true
  37. client.rm.tableMetaCheckerInterval = 60000
  38. client.rm.sqlParserType =druid
  39. client.rm.reportSuccessEnable = false
  40. client.rm.sagaBranchRegisterEnable = false
  41. client.rm.sagaJsonParser =fastjson
  42. client.rm.tccActionInterceptorOrder =- 2147482648
  43. client.tm.commitRetryCount = 5
  44. client.tm.rollbackRetryCount = 5
  45. client.tm.defaultGlobalTransactionTimeout = 60000
  46. client.tm.degradeCheck = false
  47. client.tm.degradeCheckAllowTimes = 10
  48. client.tm.degradeCheckPeriod = 2000
  49. client.tm.interceptorOrder =- 2147482648
  50. client.undo.dataValidation = true
  51. client.undo.logSerialization =jackson
  52. client.undo.onlyCareUpdateColumns = true
  53. server.undo.logSaveDays = 7
  54. server.undo.logDeletePeriod = 86400000
  55. client.undo.logTable =undo_log
  56. client.undo.compress.enable = true
  57. client.undo.compress. type =zip
  58. client.undo.compress.threshold = 64k
  59. # For TCC transaction mode
  60. tcc.fence.logTableName =tcc_fence_log
  61. tcc.fence.cleanPeriod = 1h
  62. #Log rule configuration, for client and server
  63. log.exceptionRate = 100
  64. #Transaction storage configuration, only for the server. The file, DB, and redis configuration values are optional.
  65. store. mode = file
  66. store. lock. mode = file
  67. store.session. mode = file
  68. #Used for password encryption
  69. store.publicKey =
  70. # If `store. mode,store. lock. mode,store.session. mode` are not equal to ` file`, you can remove the configuration block.
  71. store. file.dir = file_store / data
  72. store. file.maxBranchSessionSize = 16384
  73. store. file.maxGlobalSessionSize = 512
  74. store. file.fileWriteBufferCacheSize = 16384
  75. store. file.flushDiskMode =async
  76. store. file.sessionReloadReadSize = 100
  77. #These configurations are required if the `store mode` is `db`. If `store. mode,store. lock. mode,store.session. mode` are not equal to `db`, you can remove the configuration block.
  78. store.db.datasource =druid
  79. store.db.dbType =mysql
  80. store.db.driverClassName =com.mysql.jdbc.Driver
  81. store.db.url =jdbc:mysql: / / 127.0.0.1: 3306 /seata?useUnicode = true &rewriteBatchedStatements = true
  82. store.db.user =username
  83. store.db.password =password
  84. store.db.minConn = 5
  85. store.db.maxConn = 30
  86. store.db.globalTable = global_ table
  87. store.db.branchTable =branch_ table
  88. store.db.distributedLockTable =distributed_ lock
  89. store.db.queryLimit = 100
  90. store.db.lockTable = lock_ table
  91. store.db.maxWait = 5000
  92. #These configurations are required if the `store mode` is `redis`. If `store. mode,store. lock. mode,store.session. mode` are not equal to `redis`, you can remove the configuration block.
  93. store.redis. mode =single
  94. store.redis.single.host = 127.0.0.1
  95. store.redis.single.port = 6379
  96. store.redis.sentinel.masterName =
  97. store.redis.sentinel.sentinelHosts =
  98. store.redis.maxConn = 10
  99. store.redis.minConn = 1
  100. store.redis.maxTotal = 100
  101. store.redis.database = 0
  102. store.redis.password =
  103. store.redis.queryLimit = 100
  104. #Transaction rule configuration, only for the server
  105. server.recovery.committingRetryPeriod = 1000
  106. server.recovery.asynCommittingRetryPeriod = 1000
  107. server.recovery.rollbackingRetryPeriod = 1000
  108. server.recovery.timeoutRetryPeriod = 1000
  109. server.maxCommitRetryTimeout =- 1
  110. server.maxRollbackRetryTimeout =- 1
  111. server.rollbackRetryTimeoutUnlockEnable = false
  112. server.distributedLockExpireTime = 10000
  113. server.xaerNotaRetryTimeout = 60000
  114. server.session.branchAsyncQueueSize = 5000
  115. server.session.enableBranchAsyncRemove = false
  116. server.enableParallelRequestHandle = false
  117. #Metrics configuration, only for the server
  118. metrics.enabled = false
  119. metrics.registryType =compact
  120. metrics.exporterList =prometheus
  121. metrics.exporterPrometheusPort = 9898

         将上面seata的t配置文件config.tx导入到nacos:

        修改seata的配置文件内容 :


  
  1. # 修改store. mode为db,配置数据库连接
  2. store. mode =db
  3. store.db.dbType =mysql
  4. store.db.driverClassName =com.mysql.cj.jdbc.Driver
  5. store.db.url =jdbc:mysql: / /localhost: 3306 /seata?useUnicode = true &rewriteBatchedStatements = true
  6. store.db.user =数据库用户名
  7. store.db.password =数据库密码

        在seata/config/application.yml 修改seata配置信息:


  
  1. seata:
  2. config:
  3. type: nacos
  4. nacos:
  5. server-addr: 127.0.0.1:8848
  6. namespace:
  7. group: SEATA_GROUP
  8. data-id: seataServer.properties
  9. registry:
  10. type: nacos
  11. preferred-networks: 30.240.*
  12. nacos:
  13. application: seata-server
  14. server-addr: 127.0.0.1:8848
  15. namespace:
  16. group: SEATA_GROUP
  17. cluster: default
  18. #store:
  19. #mode: file

         最后到seata/bin目录下运行seata-server.bat即可启动seata服务。在nacos服务列表里可以看到seata已经被注册到nacos中:

 3、项目集成

        在父级工程下创建seata子级工,添加seata依赖:


  
  1. <dependency>
  2. <groupId>com.alibaba.cloud </groupId>
  3. <artifactId>spring-cloud-starter-alibaba-seata </artifactId>
  4. <exclusions>
  5. <exclusion>
  6. <groupId>io.seata </groupId>
  7. <artifactId>seata-spring-boot-starter </artifactId>
  8. </exclusion>
  9. </exclusions>
  10. </dependency>
  11. <dependency>
  12. <groupId>io.seata </groupId>
  13. <artifactId>seata-spring-boot-starter </artifactId>
  14. <version>1.5.2 </version>
  15. </dependency>

         在需要使用全局事务管理的服务中添加seata子级工程依赖,在处理数据库业务的时候添加@GlobalTransactional注解代替@Transactional注解就可以了。


转载:https://blog.csdn.net/liukangjie520/article/details/129092848
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场