Seata入门系列【9】Seata之SQL语句限制

1 前言

以下内容摘自官网(地址:http://seata.io/zh-cn/docs/user/sqlreference/sql-restrictions.html)

在使用Seata 的时候,对SQL语句还是有很多限制,所以在使用的时候需要格外注意这个问题(较新版本可能已支持)

2 SQL限制

Seata 事务目前支持 INSERT、UPDATE、DELETE 三类 DML 语法的部分功能,这些类型都是已经经过Seata开源社区的验证。SQL 的支持范围还在不断扩大,建议在本文限制的范围内使用。如果您有意帮助社区支持更多类型的SQL,请提交PR申请。

2.1 使用限制

  • 不支持 SQL 嵌套

  • 不支持多表复杂 SQL(自1.6.0版本,MySQL支持UPDATE JOIN语句)

  • 不支持存储过程、触发器

  • 部分数据库不支持批量更新,在使用 MySQL、Mariadb、PostgreSQL9.6+作为数据库时支持批量,批量更新方式如下以 Java 为例

  // use JdbcTemplate
    public void batchUpdate() {
        jdbcTemplate.batchUpdate(
            "update storage_tbl set count = count -1 where id = 1",
            "update storage_tbl set count = count -1 where id = 2"
		);
    }

    // use Statement
    public void batchUpdateTwo() {
        statement.addBatch("update storage_tbl set count = count -1 where id = 1");
        statement.addBatch("update storage_tbl set count = count -1 where id = 2");
        statement.executeBatch();
    }

2.2 DML语句

主要介绍 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_name SET 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
UPDATE JOIN UPDATE tb1_name tb1 JOIN tb2_name tb2 ON tb2.col_name=tb1.col_name SET tb1.col_name1=expr1 [, tb1.col_name2=expr2 …][ [WHERE where_definition] 是 since 1.6.0

2.3 SQL修饰

Seata 的隔离级别默认为读未提交,该模式下本文表中的 select 语句的 SQL 修饰用法都是支持的;使用 for update 代理可以让 Seata 达到读已提交,该模式下 select 语句的用法只能部分支持。

2.3.1 DML语句支持

类型 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, … ]

2.3.2 Select语句支持

类型 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

2.4 函数

下面的表列出了 DQL 语句和 DML 语句对函数的支持情况。需要注意的是,在 DML 语句中使用函数,不能将其作为主键

2.4.1 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()

2.4.2 DQL语句支持

类型 读未提交 读已提交
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()

你可能感兴趣的:(微服务,seata,sql,数据库,seata,后端,分布式事务,微服务)