赞
踩
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
注意:
在引入pom
需要注意SpringCloudAlibaba
的版本,版本对应关系查询,比如:
如果SpringCloudAlibaba
与Seata
的默认版本不对应时,可以单独引入seata
依赖,比如:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<!--版本较低,因此排除-->
<exclusion>
<artifactId>seata-spring-boot-starter</artifactId>
<groupId>io.seata</groupId>
</exclusion>
</exclusions>
</dependency>
<!--seata starter 采用1.4.2版本-->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.4.2</version>
</dependency>
在微服务客户端连接的数据库中建立undo_log
表,语句如下:
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:
enabled: true
application-id: ${spring.application.name}
# 事务组的名称,对应service.vgroupMapping.default_tx_group=xxx中配置的default_tx_group
tx-service-group: default_tx_group
# 配置事务组与集群的对应关系
service:
vgroup-mapping:
# default_tx_group为事务组的名称,default为集群名称(与registry.conf中的一致)
default_tx_group: default
disable-global-transaction: false
registry:
type: nacos
nacos:
application: seata-server
server-addr: 112.15.114.18:8848
group: SEATA_GROUP
namespace: 64ed9ca7-d705-4655-b4e4-f824e420a12a
username: nacos
password: nacos
# registry.conf中,配置cluster名称
cluster: default
config:
type: nacos
nacos:
server-addr: 112.15.114.18:8848
group: SEATA_GROUP
namespace: 64ed9ca7-d705-4655-b4e4-f824e420a12a
username: nacos
password: nacos
# nacos配置中心配置的dataId
data-id: seataServer.properties
全局事务注解:
@GlobalTransactional
在事务发起的微服务方法上加上注解@GlobalTransactional
表示全局事务中的一个TM。
注意:异常不能被捕获需要抛出,事务才会发起回滚
比如:
@RestController
@RequestMapping("test")
public class TestController {
@GetMapping("/insert")
@GlobalTransactional
public void selectUserWageByUserId() {
......
......
// 如果RootContext.getXID()不为空,则表示seata生效
System.out.println("RootContext.getXID():" + RootContext.getXID());
}
}
效果:
可以看到在undo_log
以及seata服务
的global_table
、branch_table
、lock_table
中存在seata
执行分布式事务时的数据。
隔离级别:
Seata的隔离级别默认为读未提交
。
数据源支持情况如下:
参考:https://seata.io/zh-cn/docs/user/datasource.html
Seata 事务目前支持 INSERT、UPDATE、DELETE 三类 DML 语法的部分功能,这些类型都是已经经过Seata开源社区的验证。
使用限制:
参考:https://seata.io/zh-cn/docs/user/sqlreference/sql-restrictions.html
DML 语句类型、SQL 实例以及 Seata 是否支持情况:
类型 | SQL 实例 | 是否支持 |
---|---|---|
INSERT | INSERT INTO tb1_name (col_name,...) VALUES ({expr | FAULT},...),(...),... 或 INSERT INTO tb1_name SET col_name={expr | DEFAULT}, ... 或INSERT INTO tb1_name (col_name,...) VALUES ({expr | FAULT},...) ON DUPLICATE KEY UPDATE field1=value1,...; | 是 |
UPDATE | UPDATE tb1_nameSET col_name1=expr1 [, col_name2=expr2 ...][WHERE where_definition] | 是 |
DELETE | DELETE FROM tb1_name [WHERE where_definition] | 是 |
SELECT | SELECT [ALL | DISTINCT | DISTINCTROW ]select_expr, ... FROM tb1_name[WHERE where_definition] | 是 |
REPLACE | REPLACE [LOW_PRIORITY | DELAYED][INTO] tb1_name [(col_name,...)]VALUES ({expr | DEFAULT},...),(...),... 或REPLACE [LOW_PRIORITY | DELAYED][INTO] tb1_nameSET col_name={expr | DEFAULT}, ... | 否 |
TRUNCATE | TRUNCATE [TABLE] tb1_name | 否 |
参考:https://seata.io/zh-cn/docs/user/sqlreference/dml.html
Seata 的隔离级别默认为读未提交,该模式下本文表中的 select 语句的 SQL 修饰用法都是支持的;使用 for update 代理可以让 Seata 达到读已提交,该模式下 select 语句的用法只能部分支持。
类型 | SQL 实例 | 是否支持 |
---|---|---|
AND & OR | UPDATE … WHERE col_name1=expr1 AND col_name2= expr2 | 是 |
LIKE | UPDATE ... WHERE col_name1 LIKE 'NE' | 是 |
通配符 | UPDATE ... WHERE col_name1 LIKE 'NE%' | 是 |
BETWEEN | UPDATE ... WHERE col_name1 BETWEEN expr1 AND expr2 | 是 |
ON DUPLICATE | INSERT INTO tb1_name [(col_name,...)]VALUES ({expr | DEFAULT},...),(...),...[ ON DUPLICATE KEY UPDATE col_name=expr, ... ] | 是 |
类型 | SQL 实例 | 读未提交 | 读已提交 |
---|---|---|---|
AND & OR | SELECT * FROM tb1_name WHERE col_name1=expr1 AND col_name2= expr2 | 是 | 是 |
ORDER BY | SELECT col_name1, col_name2 FROM tb1_name ORDER BY col_name1 | 是 | 是 |
GROUP BY | SELECT col_name1, col_name2 FROM tb1_name GROUP BY col_name1 | 是 | 是 |
LIKE | SELECT col_name1, col_name2 FROM tb1_name WHERE col_name1 LIKE 'NE' | 是 | 是 |
通配符 | SELECT col_name1, col_name2 FROM tb1_name WHERE col_name1 LIKE 'NE%' | 是 | 是 |
EXISTS | SELECT col_name1, col_name2 FROM tb1_name WHERE EXISTS (expr1) | 是 | 是 |
IN | SELECT col_name1, col_name2 FROM tb1_name WHERE col_name1 IN (expr1, expr2,...) | 是 | 是 |
BETWEEN | SELECT col_name1, col_name2 FROM tb1_name WHERE col_name1 BETWEEN expr1 AND expr2 | 是 | 是 |
ON DUPLICATE | INSERT INTO tb1_name [(col_name,…)]VALUES ({expr | DEFAULT},…),(…),…[ ON DUPLICATE KEY UPDATE col_name=expr, … ] | 是 | 是 |
ALIASES | SELECT t1. col_name1, t2.col_name2 FROM tb1_name AS t1, tb2_name AS t2 WHERE t1. col_name=expr AND t2. col_name=expr | 是 | 是 |
TOP | SELECT TOP 2 * FROM tb1_name | 是 | 是 |
LIMIT | SELECT col_name1, col_name2 FROM tb1_name LIMIT 5 | 是 | 是 |
JOININNER JOINLEFT JOINRIGHT JOINFULL JOIN | SELECT col_name1, col_name2 FROM tb1_name JOIN tb2_name>ON tb1_name. col_name1= tb2_name. col_name1 | 是 | 否 |
UNIONUNION ALLSELECT INTO | SELECT col_name1, col_name2 FROM tb1_name UNION SELECT col_name1, col_name2 FROM tb2_name | 是 | 否 |
参考:https://seata.io/zh-cn/docs/user/sqlreference/sql-decoration.html
表列出了 DQL 语句和 DML 语句对函数的支持情况。需要注意的是,在 DML 语句中使用函数,不能将其作为主键。
类型 | 是否支持 |
---|---|
CONCAT(string2[,…]) | 是 |
INSTR(string,substring) | 是 |
LCASE(string2) | 是 |
LEFT(string2,length) | 是 |
LENGTH(string) | 是 |
LOAD_FILE(file_name) | 是 |
LOCATE(substring,string[,start_position]) | 是 |
LPAD(string2,length,pad) | 是 |
LTRIM(string2) | 是 |
REPEAT(string2,count) | 是 |
REPLACE(str,search_str,replace_str) | 是 |
RPAD(string2,length,pad) | 是 |
RTRIM(string2) | 是 |
STRCMP(string1,string2) | 是 |
SUBSTRING(str,position[,length]) | 是 |
TRIM([[BOTH|LEADING|TRAILING][padding]FROM]string2) | 是 |
UCASE(string2) | 是 |
RIGHT(string2,length) | 是 |
SPACE(count) | 是 |
ABS(number2) | 是 |
BIN(decimal_number) | 是 |
CEILING(number2) | 是 |
CONV(number2,from_base,to_base) | 是 |
FLOOR(number2) | 是 |
FORMAT(number,decimal_places) | 是 |
HEX(DecimalNumber) | 是 |
LEAST(number,number2[,…]) | 是 |
MOD(numerator,denominator) | 是 |
POWER(number,power) | 是 |
RAND([seed]) | 是 |
ROUND(number[,decimals]) | 是 |
SIGN(number2) | 是 |
SQRT(number2) | 是 |
ADDTIME(date2,time_interval) | 是 |
CONVERT_TZ(datetime2,fromTZ,toTZ) | 是 |
CURRENT_DATE() | 是 |
CURRENT_TIME() | 是 |
CURRENT_TIMESTAMP() | 是 |
DATE(datetime) | 是 |
DATE_ADD(date2,INTERVALd_valued_type) | 是 |
DATE_FORMAT(datetime,FormatCodes) | 是 |
DATE_SUB(date2,INTERVALd_valued_type) | 是 |
DATEDIFF(date1,date2) | 是 |
DAY(date) | 是 |
DAYNAME(date) | 是 |
DAYOFWEEK(date) | 是 |
DAYOFYEAR(date) | 是 |
EXTRACT(interval_nameFROMdate) | 是 |
MAKEDATE(year,day) | 是 |
MAKETIME(hour,minute,second) | 是 |
MONTHNAME(date) | 是 |
NOW() | 是 |
SEC_TO_TIME(seconds) | 是 |
STR_TO_DATE(string,format) | 是 |
TIMEDIFF(datetime1,datetime2) | 是 |
TIME_TO_SEC(time) | 是 |
WEEK(date_time[,start_of_week]) | 是 |
YEAR(datetime) | 是 |
DAYOFMONTH(datetime) | 是 |
HOUR(datetime) | 是 |
LAST_DAY(date) | 是 |
MICROSECOND(datetime) | 是 |
MONTH(datetime) | 是 |
MINUTE(datetime) | 是 |
FIRST() | 否 |
LAST() | 否 |
MIN() | 否 |
MAX() | 否 |
AVG() | 否 |
SUM() | 否 |
COUNT() | 否 |
类型 | 读未提交 | 读已提交 |
---|---|---|
CONCAT(string2[,…]) | 是 | 是 |
INSTR(string,substring) | 是 | 是 |
LCASE(string2) | 是 | 是 |
LEFT(string2,length) | 是 | 是 |
LENGTH(string) | 是 | 是 |
LOAD_FILE(file_name) | 是 | 是 |
LOCATE(substring,string[,start_position]) | 是 | 是 |
LPAD(string2,length,pad) | 是 | 是 |
LTRIM(string2) | 是 | 是 |
REPEAT(string2,count) | 是 | 是 |
REPLACE(str,search_str,replace_str) | 是 | 是 |
RPAD(string2,length,pad) | 是 | 是 |
RTRIM(string2) | 是 | 是 |
STRCMP(string1,string2) | 是 | 是 |
SUBSTRING(str,position[,length]) | 是 | 是 |
TRIM([[BOTH|LEADING|TRAILING][padding]FROM]string2) | 是 | 是 |
UCASE(string2) | 是 | 是 |
RIGHT(string2,length) | 是 | 是 |
SPACE(count) | 是 | 是 |
ABS(number2) | 是 | 是 |
BIN(decimal_number) | 是 | 是 |
CEILING(number2) | 是 | 是 |
CONV(number2,from_base,to_base) | 是 | 是 |
FLOOR(number2) | 是 | 是 |
FORMAT(number,decimal_places) | 是 | 是 |
HEX(DecimalNumber) | 是 | 是 |
LEAST(number,number2[,…]) | 是 | 是 |
MOD(numerator,denominator) | 是 | 是 |
POWER(number,power) | 是 | 是 |
RAND([seed]) | 是 | 是 |
ROUND(number[,decimals]) | 是 | 是 |
SIGN(number2) | 是 | 是 |
SQRT(number2) | 是 | 是 |
ADDTIME(date2,time_interval) | 是 | 是 |
CONVERT_TZ(datetime2,fromTZ,toTZ) | 是 | 是 |
CURRENT_DATE() | 是 | 是 |
CURRENT_TIME() | 是 | 是 |
CURRENT_TIMESTAMP() | 是 | 是 |
DATE(datetime) | 是 | 是 |
DATE_ADD(date2,INTERVALd_valued_type) | 是 | 是 |
DATE_FORMAT(datetime,FormatCodes) | 是 | 是 |
DATE_SUB(date2,INTERVALd_valued_type) | 是 | 是 |
DATEDIFF(date1,date2) | 是 | 是 |
DAY(date) | 是 | 是 |
DAYNAME(date) | 是 | 是 |
DAYOFWEEK(date) | 是 | 是 |
DAYOFYEAR(date) | 是 | 是 |
EXTRACT(interval_nameFROMdate) | 是 | 是 |
MAKEDATE(year,day) | 是 | 是 |
MAKETIME(hour,minute,second) | 是 | 是 |
MONTHNAME(date) | 是 | 是 |
NOW() | 是 | 是 |
SEC_TO_TIME(seconds) | 是 | 是 |
STR_TO_DATE(string,format) | 是 | 是 |
TIMEDIFF(datetime1,datetime2) | 是 | 是 |
TIME_TO_SEC(time) | 是 | 是 |
WEEK(date_time[,start_of_week]) | 是 | 是 |
YEAR(datetime) | 是 | 是 |
DAYOFMONTH(datetime) | 是 | 是 |
HOUR(datetime) | 是 | 是 |
LAST_DAY(date) | 是 | 是 |
MICROSECOND(datetime) | 是 | 是 |
MONTH(datetime) | 是 | 是 |
MINUTE(datetime) | 是 | 是 |
FIRST() | 是 | 否 |
LAST() | 是 | 否 |
MIN() | 是 | 否 |
MAX() | 是 | 否 |
AVG() | 是 | 否 |
SUM() | 是 | 否 |
COUNT() | 是 | 否 |
参考:https://seata.io/zh-cn/docs/user/sqlreference/function.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。