注意:数据库表的主键问题!!!!!如果要使用seata,那么对应的表必须要有主键存在。
1.引入依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-seata</artifactId>
<version>2.0.0.RELEASE</version>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-all</artifactId>
<version>1.0.0</version>
</dependency>
配置文件:
1. registry.conf:配置注册中心和配置中心,默认是file。
2. file.conf:seata工作规则信息
3. DataSourceConfig:配置代理数据源实现分支事务,如果没有注入,事务无法成功回滚
registry.conf(注册中心和配置中心在一个文件中)
文件包含两部分配置:
- 注册中心
- 配置中心
注册中心:
registry { # 注册中心配置
# 可选项:file 、nacos 、eureka、redis、zk
type = "file" # 指定nacos注册中心,默认是file。
nacos {
serverAddr = "127.0.0.1:8848"
namespace = "public"
cluster = "default"
}
eureka {
serviceUrl = "http://localhost:1001/eureka"
application = "default"
weight = "1"
}
redis {
serverAddr = "localhost:6381"
db = "0"
}
zk {
cluster = "default"
serverAddr = "127.0.0.1:2181"
session.timeout = 6000
connect.timeout = 2000
}
file {
name = "file.conf"
}
}
配置中心
config { # 配置中心
# 可选项:file、nacos 、apollo、zk
type = "file" # 指向file配置中心,也可以指向nacos等其他注册中心
nacos {
serverAddr = "localhost"
namespace = "public"
cluster = "default"
}
apollo {
app.id = "fescar-server"
apollo.meta = "http://192.168.1.204:8801"
}
zk {
serverAddr = "127.0.0.1:2181"
session.timeout = 6000
connect.timeout = 2000
}
file {
name = "file.conf" # 通过file.conf配置seata参数,指向第二个配置文件
}
}
file.conf
从下面开始到数据库配置信息都在file.conf文件中
该文件的命名取决于registry.conf配置中心的配置
由于registry.conf中配置的是
也就是说:file.conf文件名取决于registry的配置中心配置,如果registry配置的配置中心不是file,可以没有改文件。例如:如果配置中心是nacos,这是file.conf文件就不需要了,把file.conf文件内容交给nacos就可
网络传输配置:
transport {
# tcp udt unix-domain-socket
type = "TCP"
#NIO NATIVE
server = "NIO"
#enable heartbeat
heartbeat = true
#thread factory for netty
thread-factory {
boss-thread-prefix = "NettyBoss"
worker-thread-prefix = "NettyServerNIOWorker"
server-executor-thread-prefix = "NettyServerBizHandler"
share-boss-worker = false
client-selector-thread-prefix = "NettyClientSelector"
client-selector-thread-size = 1
client-worker-thread-prefix = "NettyClientWorkerThread"
# netty boss thread size,will not be used for UDT
boss-thread-size = 1
#auto default pin or 8
worker-thread-size = 8
}
}
事务日志存储配置:该部分内容参照account-service中的file.conf配置
store {
## store mode: file、db
mode = "file" # 存储方式file、db
## file store
file {
dir = "sessionStore"
# branch session size , if exceeded first try compress lockkey, still exceeded throws exceptions
max-branch-session-size = 16384
# globe session size , if exceeded throws exceptions
max-global-session-size = 512
# file buffer size , if exceeded allocate new buffer
file-write-buffer-cache-size = 16384
# when recover batch read size
session.reload.read_size = 100
# async, sync
flush-disk-mode = async
}
## database store
db {
driver_class = ""
url = ""
user = ""
password = ""
}
}
当前微服务在seata服务器中注册的信息配置:
${spring.applicaiton.name}是你的服务名
default.grouplist = "127.0.0.1:8091"*#seata-server服务器地址,默认是8091
service {
#vgroup->rgroup
#必须和服务名一致:${spring.applicaiton.name}
vgroup_mapping.${spring.application.name}-fescar-service-group = "default"
#only support single node
default.grouplist = "127.0.0.1:8091"*#seata-server服务器地址,默认是8091
#degrade current not support
enableDegrade = false
#disable
disable = false
}
客户端相关工作的机制
undo_log表在每个库中都存在
client {
rm {
async.commit.buffer.limit = 10000
lock {
retry.internal = 10
retry.times = 30
retry.policy.branch-rollback-on-conflict = true
}
report.retry.count = 5
table.meta.check.enable = false
report.success.enable = true
}
tm {
commit.retry.count = 5
rollback.retry.count = 5
}
undo {
data.validation = true
log.serialization = "jackson"
log.table = "undo_log"
}
log {
exceptionRate = 100
}
support {
# auto proxy the DataSource bean
spring.datasource.autoproxy = false
}
}
每个数据库都要有一张undo_log日志表,sql如下:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for undo_log
-- ----------------------------
DROP TABLE IF EXISTS `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,
`ext` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
java的DataSourceConfig配置
每一个微服务原来自己的数据源都必须使用DataSourceProxy代理,这样seata才能掌控所有事务。
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DruidDataSource druidDataSource() {
return new DruidDataSource();
}
/**
* 需要将 DataSourceProxy 设置为主数据源,否则事务无法回滚
*
* @param druidDataSource The DruidDataSource
* @return The default datasource
*/
@Primary
@Bean("dataSource")
public DataSource dataSource(DruidDataSource druidDataSource) {
return new DataSourceProxy(druidDataSource);
}
}