nacos + seata
nacos服务的部署这里就不介绍了,先启动nacos服务,用于注册/发现、配置中心seata服务部署下载服务的压缩包,https://github.com/seata/seata/releases下载源码包,主要是用到一些配置文件修改registry.conf文件registry {# file 、nacos 、eureka、redis、zk、consul、etcd3、sofatype = "na
·
- nacos服务的部署这里就不介绍了,先启动nacos服务,用于注册/发现、配置中心
- 下载seata服务的压缩包,https://github.com/seata/seata/releases
- 下载seata开发源码包,主要是用到一些配置文件
- 解压seata服务压缩包,修改registry.conf文件
-
registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" loadBalance = "RandomLoadBalance" loadBalanceVirtualNodes = 10 nacos { application = "seata-server" serverAddr = "127.0.0.1:8848" group = "SEATA_GROUP" namespace = "" cluster = "default" username = "nacos" password = "nacos" } } config { # file、nacos 、apollo、zk、consul、etcd3 type = "nacos" nacos { serverAddr = "127.0.0.1:8848" namespace = "" group = "SEATA_GROUP" username = "nacos" password = "nacos" } }
- 网上很多帖子都是先改file.conf,完全没必要,file.conf是针对本地配置时使用的,我们采用的是nacos作为注册和配置中心,所以file.conf不需要
- 修改config.txt,服务解压包里没有,从开发源码包里找,位于seata-develop.zip\seata-develop\script\config-center 目录下,复制到seata根目录
-
transport.type=TCP transport.server=NIO transport.heartbeat=true transport.enableClientBatchSendRequest=false transport.threadFactory.bossThreadPrefix=NettyBoss transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler transport.threadFactory.shareBossWorker=false transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector transport.threadFactory.clientSelectorThreadSize=1 transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread transport.threadFactory.bossThreadSize=1 transport.threadFactory.workerThreadSize=default transport.shutdown.wait=3 transport.serialization=seata transport.compressor=none service.vgroupMapping.my_test_tx_group=default service.default.grouplist=127.0.0.1:8091 service.enableDegrade=false service.disableGlobalTransaction=false client.rm.asyncCommitBufferLimit=10000 client.rm.lock.retryInterval=10 client.rm.lock.retryTimes=30 client.rm.lock.retryPolicyBranchRollbackOnConflict=true client.rm.reportRetryCount=5 client.rm.tableMetaCheckEnable=false client.rm.sqlParserType=druid client.rm.reportSuccessEnable=false client.rm.sagaBranchRegisterEnable=false client.tm.commitRetryCount=5 client.tm.rollbackRetryCount=5 client.tm.defaultGlobalTransactionTimeout=60000 client.tm.degradeCheck=false client.tm.degradeCheckAllowTimes=10 client.tm.degradeCheckPeriod=2000 client.undo.dataValidation=true client.undo.logSerialization=jackson client.undo.onlyCareUpdateColumns=true client.undo.logTable=undo_log store.mode=db store.file.dir=file_store/data store.file.maxBranchSessionSize=16384 store.file.maxGlobalSessionSize=512 store.file.fileWriteBufferCacheSize=16384 store.file.flushDiskMode=async store.file.sessionReloadReadSize=100 store.db.datasource=druid store.db.dbType=mysql store.db.driverClassName=com.mysql.jdbc.Driver store.db.url=jdbc:mysql://127.0.0.1:3306/db_seata?useUnicode=true store.db.user=root store.db.password=root store.db.minConn=5 store.db.maxConn=30 store.db.globalTable=global_table store.db.branchTable=branch_table store.db.queryLimit=100 store.db.lockTable=lock_table store.db.maxWait=5000 store.redis.host=127.0.0.1 store.redis.port=6379 store.redis.maxConn=10 store.redis.minConn=1 store.redis.database=0 store.redis.password=null store.redis.queryLimit=100 server.recovery.committingRetryPeriod=1000 server.recovery.asynCommittingRetryPeriod=1000 server.recovery.rollbackingRetryPeriod=1000 server.recovery.timeoutRetryPeriod=1000 server.maxCommitRetryTimeout=-1 server.maxRollbackRetryTimeout=-1 server.rollbackRetryTimeoutUnlockEnable=false server.undo.logSaveDays=7 server.undo.logDeletePeriod=86400000 log.exceptionRate=100 metrics.enabled=false metrics.registryType=compact metrics.exporterList=prometheus metrics.exporterPrometheusPort=9898
主要修改点为store.mode=db,store.db.url=jdbc:mysql://127.0.0.1:3306/db_seata?useUnicode=true,store.db.user=root,store.db.password=root,这个配置表示seata服务端使用数据库存储,根据自己实际情况填写
- 将nacos-config.sh复制到seata的conf目录,目录为:seata-develop.zip\seata-develop\script\config-center\nacos
- 用命令将配置文件导入到nacos配置中心,sh nacos-config.sh -h 127.0.0.1 -p 8848 -g SEATA_GROUP
- seata服务的表创建语句
-
CREATE TABLE IF NOT EXISTS `global_table` ( `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `status` TINYINT NOT NULL, `application_id` VARCHAR(32), `transaction_service_group` VARCHAR(32), `transaction_name` VARCHAR(128), `timeout` INT, `begin_time` BIGINT, `application_data` VARCHAR(2000), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`xid`), KEY `idx_gmt_modified_status` (`gmt_modified`, `status`), KEY `idx_transaction_id` (`transaction_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8; -- the table to store BranchSession data CREATE TABLE IF NOT EXISTS `branch_table` ( `branch_id` BIGINT NOT NULL, `xid` VARCHAR(128) NOT NULL, `transaction_id` BIGINT, `resource_group_id` VARCHAR(32), `resource_id` VARCHAR(256), `branch_type` VARCHAR(8), `status` TINYINT, `client_id` VARCHAR(64), `application_data` VARCHAR(2000), `gmt_create` DATETIME(6), `gmt_modified` DATETIME(6), PRIMARY KEY (`branch_id`), KEY `idx_xid` (`xid`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8; -- the table to store lock data CREATE TABLE IF NOT EXISTS `lock_table` ( `row_key` VARCHAR(128) NOT NULL, `xid` VARCHAR(96), `transaction_id` BIGINT, `branch_id` BIGINT NOT NULL, `resource_id` VARCHAR(256), `table_name` VARCHAR(32), `pk` VARCHAR(36), `gmt_create` DATETIME, `gmt_modified` DATETIME, PRIMARY KEY (`row_key`), KEY `idx_branch_id` (`branch_id`) ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
seata客户端建表语句,也就是各个微服务使用的数据库都要有表,用于事务回滚
-
-- for AT mode you must to init this sql for you business database. the seata server not need it. CREATE TABLE IF NOT EXISTS `undo_log` ( `branch_id` BIGINT(20) NOT NULL COMMENT 'branch transaction id', `xid` VARCHAR(100) NOT NULL COMMENT 'global transaction id', `context` VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization', `rollback_info` LONGBLOB NOT NULL COMMENT 'rollback info', `log_status` INT(11) 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 KEY `ux_undo_log` (`xid`, `branch_id`) ) ENGINE = InnoDB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
启动seata服务,从bin目录双击seata-server.bat
- 接下来是重头了,代码阶段,我这里是分三个工程,一个consumer,二个provider
- pom.xml完全一样
-
<?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.2.11.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>cn.demo</groupId> <artifactId>seata-consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>seata-consumer</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.22</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-seata</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2.2.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR9</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> </project>
consumer工程的application.yml
-
server: port: 8080 spring: datasource: druid: driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 username: root password: root application: name: seata-consumer cloud: nacos: server-addr: 127.0.0.1:8848 seata: enabled: true application-id: seata-consumer tx-service-group: my_test_tx_group enable-auto-data-source-proxy: true use-jdk-proxy: false excludes-for-auto-proxying: firstClassNameForExclude,secondClassNameForExclude config: type: nacos nacos: namespace: "" server-addr: 127.0.0.1:8848 group: SEATA_GROUP username: "nacos" password: "nacos" registry: type: nacos nacos: application: seata-server server-addr: 127.0.0.1:8848 group: "SEATA_GROUP" namespace: "" username: "nacos" password: "nacos"
provider1的application.yml
-
server: port: 8081 spring: datasource: druid: driverClassName: com.mysql.cj.jdbc.Driver url: jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=utf-8&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8 username: root password: root application: name: seata-provider1 cloud: nacos: server-addr: 127.0.0.1:8848 seata: enabled: true application-id: seata-provider1 tx-service-group: my_test_tx_group enable-auto-data-source-proxy: true use-jdk-proxy: false config: type: nacos nacos: namespace: "" server-addr: 127.0.0.1:8848 group: SEATA_GROUP username: "nacos" password: "nacos" registry: type: nacos nacos: application: seata-server server-addr: 127.0.0.1:8848 group: "SEATA_GROUP" namespace: "" username: "nacos" password: "nacos"
provider2的application.yml与1的基本一样,改spring.application.mane和seata.application-id两个属性为2的
- consumer工程的代码
-
@EnableFeignClients @SpringBootApplication @MapperScan("cn.daixinmei.seata") public class SeataConsumerApplication { public static void main(String[] args) { SpringApplication.run(SeataConsumerApplication.class, args); } } @RestController public class MainController { @Autowired private MainService mainService; @RequestMapping("test1") public String test1() { mainService.test1(); return "来了!"; } @RequestMapping("test2") public String test2() { mainService.test2(); return "来了!"; } @RequestMapping("test3") public String test3() { mainService.test3(); return "来了!"; } } @Service @GlobalTransactional public class MainService { @Autowired private Provider1 provider1; @Autowired private Provider2 provider2; public void test1() { provider1.test1(); provider2.test1(); } public void test2() { provider1.test1(); provider2.test2(); } } @FeignClient("seata-provider1") public interface Provider1 { @RequestMapping("test1") public String test1(); } @FeignClient("seata-provider2") public interface Provider2 { @RequestMapping("test1") public String test1(); @RequestMapping("test2") void test2(); }
provider1工程代码
-
@SpringBootApplication @MapperScan("cn.daixinmei.seata") public class SeataProvider1Application { public static void main(String[] args) { SpringApplication.run(SeataProvider1Application.class, args); } } @RestController public class MainController { @Autowired private MainService mainService; @RequestMapping("test1") public String test1() { mainService.test1(); return "来了!"; } } @Service @Transactional public class MainService { @Autowired private MainDao mainDao; private AtomicInteger i = new AtomicInteger(); public void test1() { mainDao.insert(UUID.randomUUID().toString(), "第一个服务 - " + i.incrementAndGet()); } } public interface MainDao { @Insert("insert into t_seata (id,name) values (#{id},#{name})") void insert(@Param("id") String id, @Param("name") String name); }
provider2工程代码
-
@SpringBootApplication @MapperScan("cn.daixinmei.seata") public class SeataProvider2Application { public static void main(String[] args) { SpringApplication.run(SeataProvider2Application.class, args); } } @RestController public class MainController { @Autowired private MainService mainService; @RequestMapping("test1") public String test1() { mainService.test1(); return "来了!"; } @RequestMapping("test2") public String test2() { mainService.test2(); return "来了!"; } } @Service @Transactional public class MainService { @Autowired private MainDao mainDao; private AtomicInteger i = new AtomicInteger(); public void test1() { mainDao.insert(UUID.randomUUID().toString(), "第二个服务 - " + i.incrementAndGet()); } public void test2() { mainDao.insert(UUID.randomUUID().toString(), "第二个服务 - " + i.incrementAndGet()); System.out.println(1 / 0); } } public interface MainDao { @Insert("insert into t_seata (id,name) values (#{id},#{name})") void insert(String id, String name); }
都是我自己的demo代码,可以启动,没有问题
更多推荐
已为社区贡献1条内容
所有评论(0)