1、包含服务
nacos注册中心,配置中心
seata server
微服务A,微服务B
2、下载资源
Seata Releases
3、服务启动
1)nacos服务启动:startup.cmd -m standalone
2)配置seata
主要包括:
①修改register.conf文件,注册服务至nacos上
②修改config.txt,同步配置至nacos
③创建seata相关数据库表
1、解压seata-server-1.4.1.zip,进入seata/conf,修改register.conf文件如下:
registry {
# file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
type = "nacos"
nacos {
application = "seata-server"
serverAddr = "127.0.0.1:8848"
group = "SEATA_GROUP"
namespace = "4b24821e-b14b-43a7-b3a0-9480520ebb59"
cluster = "default"
username = "nacos"
password = "nacos"
}
}
config {
# file、nacos 、apollo、zk、consul、etcd3
type = "nacos"
nacos {
serverAddr = "127.0.0.1:8848"
namespace = "4b24821e-b14b-43a7-b3a0-9480520ebb59"
group = "SEATA_GROUP"
username = "nacos"
password = "nacos"
}
}
进入/bin目录执行
seata-server.bat -p 9000 -m file
2、解压Source code,进入script\config-center,修改config.txt文件
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
service.vgroupMapping.spring.slivloon-cloud=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
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/ali-seata?useUnicode=true
store.db.user=root
store.db.password=ares123
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
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
client.undo.logTable=undo_log
log.exceptionRate=100
transport.serialization=seata
transport.compressor=none
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898
主要修改service.vgroupMapping.spring.slivloon-cloud=default,标红为自定义事务分组,之后各服务配置文件需与之对应。其他配置自己看着改
在git环境下执行script\config-center\nacos中的nacos-config.sh,使配置同步至nacos配置中心(也可通过python环境执行py脚本)
sh nacos-config.sh -h localhost -p 8848 -t 56c94dbe-7fbe-49c2-b456-170001455569 -u nacos -w nacos
3、初始化seata相关mysql表
执行script\server\db目录下,mysql.sql文件
4、整合springcloud
搭建简单的微服务seata-pro1和seata-pro2,这里使用springdata jpa进行数据交互,仅展示主要代码部分。
业务逻辑为seata-pro1生成订单,通过feign调用seata-pro2的增加积分功能。
1、添加依赖
com.alibaba.cloud
spring-cloud-starter-alibaba-seata
2、修改配置文件
application.yml
spring:
application:
name: seata-pro1
cloud:
nacos:
#nacoss config
discovery:
server-addr: localhost:8848
namespace: 4b24821e-b14b-43a7-b3a0-9480520ebb59
ribbon:
ReadTimeout: 30000
ConnectTimeout: 30000
TIPS,测试时分支事务打断点,由于feign连接超时会报timeout错误,所以可添加ribbon相关超时配置
bootstrap.yml
spring:
cloud:
nacos:
config:
#nacos配置中心
server-addr: localhost:8848
extension-configs[0]:
data-id: db.yaml
group: dev
refresh: true
seata:
enabled: true
application-id: ${spring.application.name}
tx-service-group: spring.slivloon-cloud #此处配置自定义的seata事务分组名称
enable-auto-data-source-proxy: true #开启数据库代理
config:
type: nacos
nacos:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
group: SEATA_GROUP
registry:
type: nacos
nacos:
application: seata-server
server-addr: ${spring.cloud.nacos.discovery.server-addr}
namespace: ${spring.cloud.nacos.discovery.namespace}
3、配置代理数据源
@Configuration
@ConditionalOnClass(HikariDataSource.class)
public class DataSourceProxyConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.hikari")
public DataSource hikariDataSource() {
HikariDataSource hikariDataSource = new HikariDataSource();
return hikariDataSource;
}
@Primary
@Bean("dataSource")
public DataSourceProxy dataSourceProxy(DataSource hikariDataSource) {
return new DataSourceProxy(hikariDataSource);
}
}
4、seata-pro1服务
实体类order订单
Table(name = "sliv_order")
@Data
@Entity
@DynamicUpdate
public class Order extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(columnDefinition= "int(5) comment '买家id'")
private Integer buyerId;
@Column(columnDefinition= "int(1) comment '订单状态(0进行中,1已完成,2已取消)'")
private Integer status;
@Column(columnDefinition= "decimal(12,2) comment '订单金额'")
private Float payAmount;
@Column(columnDefinition= "varchar(90) comment '备注'")
private String remark;
}
service服务层
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class OrderService {
private final OrderDao orderDao;
private final CreditFeign creditFeign;
@GlobalTransactional
public void save(OrderDto orderDto){
Order order = new Order();
BeanUtils.copyProperties(orderDto, order);
this.orderDao.saveOne(order);
Bonus build = Bonus.builder()
.buyerId(orderDto.getBuyerId())
.bonus(orderDto.getPayAmount())
.build();
this.creditFeign.increaseAmount(build);
}
}
feign服务调用
@FeignClient(name = "seata-pro2")
public interface CreditFeign {
@PostMapping("/credit/increase")
void increaseAmount(@RequestBody Bonus bonus);
}
controller
@RestController
@RequestMapping("/order")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class OrderController {
private final OrderService orderService;
@PostMapping("/save")
public Result send(OrderDto dto){
this.orderService.save(dto);
return Result.ofSuccess();
}
}
5、seata-pro2服务
实体类credit积分
@Table(name = "sliv_credit")
@Data
@Entity
@DynamicUpdate
public class Credit extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(columnDefinition= "int(5) comment '买家id'")
private Integer buyerId;
@Column(columnDefinition= "int(1) comment '积分等级(0青铜,1王者)'")
private Integer level;
@Column(columnDefinition= "decimal(12,2) comment '积分数'")
private Float creditAmount;
@Column(columnDefinition= "varchar(90) comment '备注'")
private String remark;
}
service服务层
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CreditService {
private final CreditDao creditDao;
public void increaseAmount(Bonus bonus){
Credit credit = this.creditDao.findByBuyerId(bonus.getBuyerId());
if (credit != null) {
Float creditAmount = credit.getCreditAmount();
credit.setCreditAmount(creditAmount+bonus.getBonus());
this.creditDao.updateOne(credit);
}
}
}
feign接口
@RestController
@RequestMapping("/credit")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CreditFeignController {
private final CreditService creditService;
@PostMapping("/increase")
public void increaseAmount(@RequestBody Bonus bonus){
this.creditService.increaseAmount(bonus);
}
}
6测试
无异常情况
异常情况测试
TIPS:有个小坑,当微服务中定义了全局异常捕获@RestControllerAdvice或者使用feign降级处理,分支事务发生异常时,本地事务无法进行回滚。