Seata-Server部署
-
下载启动包
wget https://github.com/seata/seata/releases/download/v1.0.0/seata-server-1.0.0.tar.gz
建立数据库seata-server
-
创建相关表
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, `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(32) DEFAULT NULL, `transaction_service_group` varchar(32) DEFAULT NULL, `transaction_name` varchar(128) 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` bigint(20) DEFAULT NULL, `branch_id` bigint(20) NOT NULL, `resource_id` varchar(256) DEFAULT NULL, `table_name` varchar(32) DEFAULT NULL, `pk` varchar(36) DEFAULT NULL, `gmt_create` datetime DEFAULT NULL, `gmt_modified` datetime DEFAULT NULL, PRIMARY KEY (`row_key`), KEY `idx_branch_id` (`branch_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 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, PRIMARY KEY (`id`), UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-
修改file.conf配置文件
1. cd
/conf/ 2. vim file.conf 3. 定义tx-service-group: 将vgroup_mapping.my_test_tx_group = "default" 修改为-> vgroup_mapping.my_test_tx_group = "seata-server" 4. 修改store.mode="db" 5. 修改db.datasource="druid" 6. 修改数据库连接的信息 -
修改registry.conf配置文件
1. 修改registry.type="eureka" 2. 修改eureka.serviceUrl为自己eureka地址 3. 修改eureka.applicaton="seata-server" 4. 修改config.type="apollo" 5. 修改config.apollo.app.id="seata-server" 6. 修改config.apollo.apollo.meta为apollo对应地址
-
启动
1. cd
/bin/ 2. ./seata-server.sh -p 8091 -n 1 -
启动参数详解
-h: 注册到注册中心的ip -p: Server rpc 监听端口 -m: 全局事务会话信息存储模式,file、db,优先读取启动参数 -n: Server node,多个Server时,需区分各自节点,用于生成不同区间的transactionId,以免冲突 -e: 多环境配置参考 http://seata.io/en-us/docs/ops/multi-configuration-isolation.html
Seata客户端使用
注:seata的配置较多,但是1.0.0版本里面Apollo配置源码只支持使用application的namespace。
- 在pom中增加依赖
com.alibaba.cloud
spring-cloud-alibaba-seata
seata-all
io.seata
io.seata
seata-all
1.0.0
- 将DataSource用seata包内的DataSourceProxy代理
@Primary @Bean("dataSource") public DataSourceProxy dataSourceProxy(DataSource druidDataSource) { return new DataSourceProxy(druidDataSource); }
- SqlSessionFactory使用代理后的DataSource
@Bean(name = "sqlSessionFactory") public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSourceProxy); bean.setTypeAliasesPackage("com.test.entity"); // 分页插件 PageHelper pageHelper = new PageHelper(); Properties properties = new Properties(); properties.setProperty("reasonable", "true"); // properties.setProperty("supportMethodsArguments", "true"); properties.setProperty("returnPageInfo", "check"); properties.setProperty("params", "count=countSql"); pageHelper.setProperties(properties); MybatisBaseUpdateInterceptor mybatisBaseUpdateInterceptor = new MybatisBaseUpdateInterceptor(); MybatisBaseSelectInterceptor mybatisBaseSelectInterceptor = new MybatisBaseSelectInterceptor(); // 添加插件 bean.setPlugins(new Interceptor[]{pageHelper, mybatisBaseUpdateInterceptor, mybatisBaseSelectInterceptor}); // 添加XML目录 ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); try { bean.setMapperLocations(resolver.getResources("classpath*:mapper/*.xml")); // 设置过滤_ org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); configuration.setMapUnderscoreToCamelCase(true); bean.setConfiguration(configuration); return bean.getObject(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } }
- application.properties增加配置
spring.cloud.alibaba.seata.tx-service-group=my_test_tx_group config.type = apollo registry.type = eureka #seata-server注册的注册中心地址,必填,不填会报错 registry.eureka.serviceUrl = http://xxx.xxx.xxx.xxx:8000/eureka
- 数据库创建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, PRIMARY KEY (`id`), UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`) ) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=utf8;
- apollo增加配置
#======================seata配置===================== transport.type = TCP transport.server = NIO transport.heartbeat = true transport.enable-client-batch-send-request = true #thread factory for netty transport.thread-factory.boss-thread-prefix = NettyBoss transport.thread-factory.worker-thread-prefix = NettyServerNIOWorker transport.thread-factory.server-executor-thread-prefix = NettyServerBizHandler transport.thread-factory.share-boss-worker = false transport.thread-factory.client-selector-thread-prefix = NettyClientSelector transport.thread-factory.client-selector-thread-size = 1 transport.thread-factory.client-worker-thread-prefix = NettyClientWorkerThread # netty boss thread size,will not be used for UDT transport.thread-factory.boss-thread-size = 1 #auto default pin or 8 transport.thread-factory.worker-thread-size = 8 transport.shutdown.wait = 3 transport.serialization = seata transport.compressor = none #transaction service group mapping service.vgroup_mapping.my_test_tx_group = seata-server service.enableDegrade = false #disable seata service.disableGlobalTransaction = false client.rm.async.commit.buffer.limit = 10000 client.rm.lock.retry.internal = 10 client.rm.lock.retry.times = 30 client.rm.lock.retry.policy.branch-rollback-on-conflict = true client.rm.report.retry.count = 5 client.rm.table.meta.check.enable = false client.rm.report.success.enable = true client.tm.commit.retry.count = 5 client.tm.rollback.retry.count = 5 client.undo.data.validation = true client.undo.log.serialization = jackson client.undo.log.table = undo_log client.log.exceptionRate = 100 # auto proxy the DataSource bean client.support.spring.datasource.autoproxy = false #===================================================
- 在需要使用分布式事务的方法上@GlobalTransactional注解即可,且只有抛出异常才可回滚
- 调用示例
@RestController @RequestMapping("/capi/test") public class TestController { @Autowired private Server1Api server1Api; @Autowired private Server2Api server2Api; @PostMapping() @GlobalTransactional public Result create(){ Result test1 = server1Api.test(); Result test = server2Api.test(); if(!"00".equals(test.getRespCode())){ throw new RuntimeException("xxxxxx"); } return Result.ok(); } }