Spring集成Seata方式(案例演示)
作者:Demonor_
Seata的集成方式有:
1. Seata-All
2. Seata-Spring-Boot-Starter
3. Spring-Cloud-Starter-Seata
本案例使用Seata-All演示:
第一步:下载Seata
第二步:为了更好看到效果,我们将Seata的数据存储改为db
将seata\script\server\db\mysql.sql语句在mysql中执行,创建相关表
然后修改seata配置文件,相关配置可以参考application.example.yml,此处修改mode为db并且配置db相关配置
启动seata:
第三步:开始集成Seata
1.在我们的项目pom.xml引入seata包(1.5.x有bug,我们使用1.4.2)
<!--seata--> <dependency> <groupId>io.seata</groupId> <artifactId>seata-all</artifactId> </dependency> <dependency> <groupId>com.esotericsoftware</groupId> <artifactId>kryo</artifactId> </dependency> <dependency> <groupId>de.javakaffee</groupId> <artifactId>kryo-serializers</artifactId> </dependency>
2.application.properties
#环境配置 spring.profiles.active=dev spring.application.name=user-service-provider dubbo.application.id=user-service dubbo.application.name=user-service #dubbo.protocol.port=-1 #dubbo.protocol.name=dubbo #多协议支持 dubbo.protocols.tri.name=tri dubbo.protocols.tri.port=-1 dubbo.protocols.tri.id=tri dubbo.protocols.dubbo.name=dubbo dubbo.protocols.dubbo.port=-1 dubbo.protocols.dubbo.id=dubbo #序列化方式 dubbo.protocols.dubbo.serialization=kryo dubbo.application.logger=log4j #调用信息跟踪-log4j 日志 #dubbo.protocol.accesslog=true #调用信息跟踪-将访问日志输出到指定文件 #dubbo.protocol.accesslog=/log/access.log #是否简化 url #dubbo.registry.simplified=true #dubbo.registry.id=zk-registry #dubbo.registry.address=zookeeper://192.168.1.105:2181?timeout=20000 #dubbo.config-center.address=zookeeper://192.168.1.105:2181?timeout=20000 #dubbo.metadata-report.address=zookeeper://192.168.1.105:2181?timeout=20000 #多注册中心 #dubbo.registries.zk-registry.id=zk-registry #dubbo.registries.zk-registry.address=zookeeper://192.168.1.105:2181?timeout=20000&blockUntilConnectedWait=30 dubbo.registries.nacos-registry.id=nacos-registry dubbo.registries.nacos-registry.address=nacos://192.168.1.105:8848 #dubbo.registries.nacos-registry.address=nacos://192.168.1.105:8848?namespace=2e73933a-34d4-4fba-b21e-f08cd9b8adc9 dubbo.registry.use-as-config-center=false dubbo.registry.use-as-metadata-center=false #nacos配置中心 nacos.config.server-addr=192.168.1.105:8848 #mybatis mybatis.mapper-locations= classpath*:com/lee/demo/dubbo/demo/dao/*Mapper.xml mybatis.type-aliases-package=com.lee.demo.dubbo.demo.entity #datasource spring.datasource.url=jdbc:mysql://localhost:3308/coupon-platform?useUnicode=true&characterEncoding=utf8&useOldAliasMetadataBehavior=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=Aa1225102411 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
3.在resources目录下添加配置文件file.conf和registry.conf,seata会扫描这两个配置文件从而获取相关配置。
registry.conf:
registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "file" file { name = "file.conf" } } config { # file、nacos 、apollo、zk、consul、etcd3 type = "file" file { name = "file.conf" } }
file.conf:
transport { # tcp, unix-domain-socket type = "TCP" #NIO, NATIVE server = "NIO" #enable heartbeat heartbeat = true # the tm client batch send request enable enableTmClientBatchSendRequest = false # the rm client batch send request enable enableRmClientBatchSendRequest = true # the rm client rpc request timeout rpcRmRequestTimeout = 2000 # the tm client rpc request timeout rpcTmRequestTimeout = 10000 # the tc client rpc request timeout rpcTcRequestTimeout = 5000 #thread factory for netty threadFactory { bossThreadPrefix = "NettyBoss" workerThreadPrefix = "NettyServerNIOWorker" serverExecutorThread-prefix = "NettyServerBizHandler" shareBossWorker = false clientSelectorThreadPrefix = "NettyClientSelector" clientSelectorThreadSize = 1 clientWorkerThreadPrefix = "NettyClientWorkerThread" # netty boss thread size bossThreadSize = 1 #auto default pin or 8 workerThreadSize = "default" } shutdown { # when destroy server, wait seconds wait = 3 } serialization = "seata" compressor = "none" } service { #transaction service group mapping vgroupMapping.demo-tx-default-group = "default" #only support when registry.type=file, please don't set multiple addresses default.grouplist = "192.168.8.133:8091" #degrade, current not support enableDegrade = false #disable seata disableGlobalTransaction = false } client { rm { asyncCommitBufferLimit = 10000 lock { retryInterval = 10 retryTimes = 30 retryPolicyBranchRollbackOnConflict = true } reportRetryCount = 5 tableMetaCheckEnable = false tableMetaCheckerInterval = 60000 reportSuccessEnable = false sagaBranchRegisterEnable = false sagaJsonParser = "fastjson" sagaRetryPersistModeUpdate = false sagaCompensatePersistModeUpdate = false tccActionInterceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000 } tm { commitRetryCount = 5 rollbackRetryCount = 5 defaultGlobalTransactionTimeout = 60000 degradeCheck = false degradeCheckPeriod = 2000 degradeCheckAllowTimes = 10 interceptorOrder = -2147482648 #Ordered.HIGHEST_PRECEDENCE + 1000 } undo { dataValidation = true onlyCareUpdateColumns = true logSerialization = "kryo" logTable = "undo_log" compress { enable = true # allow zip, gzip, deflater, 7z, lz4, bzip2, zstd default is zip type = zip # if rollback info size > threshold, then will be compress # allow k m g t threshold = 64k } } loadBalance { type = "RandomLoadBalance" virtualNodes = 10 } } log { exceptionRate = 100 } tcc { fence { # tcc fence log table name logTableName = tcc_fence_log # tcc fence log clean period cleanPeriod = 1h } }
4.编写Seata全局事务扫描器配置类SeataTransctionConfig:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import io.seata.spring.annotation.GlobalTransactionScanner; @Configuration public class SeataTransctionConfig { @Bean public GlobalTransactionScanner globalTransactionScanner() { String txServiceGroup = "demo-tx-default-group"; return new GlobalTransactionScanner(txServiceGroup); } }
注意:在file.conf中的service配置要和SeataTransctionConfig 中指定的txServiceGroup 一致
5. 由于AT模型是使用本地undo_log进行回滚,因此,我们每个事务所在的数据库中需要添加该表
在seata github中有样板,链接:https://github.com/seata/seata/tree/develop/srcipt/client/at/db
其中mysql.sql如下:
-- ---------------------------- -- Table structure for undo_log -- ---------------------------- DROP TABLE IF EXISTS `undo_log`; CREATE TABLE `undo_log` ( `branch_id` bigint NOT NULL COMMENT 'branch transaction id', `xid` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'global transaction id', `context` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'undo_log context,such as serialization', `rollback_info` longblob NOT NULL COMMENT 'rollback info', `log_status` int NOT NULL COMMENT '0:normal status,1:defense status', `log_created` datetime(6) NOT NULL COMMENT 'create datetime', `log_modified` datetime(6) NOT NULL COMMENT 'modify datetime', UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'AT transaction mode undo table' ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of undo_log -- ----------------------------
测试:
在抛异常之前打断点,查看数据是否成功插入过:
看到记录插入成功,并且undo_log中记录了这两个事务的日志:
断点继续往下走,触发异常,,已插入的数据被回滚,且undo_log被清空,分布式事务回滚正常。
至此,Spring集成Seata演示完毕
到此这篇关于Spring集成Seata的文章就介绍到这了,更多相关Spring集成Seata内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!