MyCATApache/Mycat-Server · error · SQLNonTransientException
You have an error in your SQL syntax, don't support lock…
Error message
You have an error in your SQL syntax, don't support lock multi tables!
What it means
visitorParse rejects multi-table LOCK TABLES. When more than one table is locked, it splits the remaining statement text and, if an extra item does not match the strict '<table> READ|WRITE' two-token form, it throws SQLNonTransientException saying the SQL syntax is wrong and multi-table locks are unsupported.
Solutions
- Issue one LOCK TABLES statement per table instead of a comma-separated list
- If you must keep multi-table syntax, keep each item exactly `table READ|WRITE` with single spaces and no aliases
- Wrap the multi-table lock in a transaction with SELECT ... FOR UPDATE instead
- Execute the lock directly on the datanode, bypassing MyCat
Example fix
// before LOCK TABLES t1 WRITE, t2 READ; // after LOCK TABLES t1 WRITE; LOCK TABLES t2 READ;
Defensive patterns
Strategy: validation
Validate before calling
String[] items = sql.split(","); if (items.length > 1) throw new IllegalArgumentException("multi-table LOCK TABLES not supported"); Try / catch
try { route(sql); } catch (SQLNonTransientException e) { if (e.getMessage().contains("don't support lock multi tables")) { splitAndLockIndividually(sql); } else throw e; } Prevention
- Issue one LOCK TABLES per table
- Avoid aliases and modifiers in lock statements routed via MyCat
- Prefer SELECT ... FOR UPDATE inside transactions
When it happens
Trigger: visitorParse on `LOCK TABLES a WRITE, b WRITE` (or similar) where a subsequent lock item's text doesn't split into exactly 2 space-separated words ending in READ or WRITE — e.g. extra whitespace tokens, AS aliases, or LOW_PRIORITY modifiers.
Common situations: Multi-table lock scripts from raw MySQL usage; aliasing (`LOCK TABLES t AS x READ`); driver-generated multi-table locks; statements with tabs or double spaces breaking the naive space split.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- lock type must be write or read
- can't lock multi-table
- can't find table define of in schema:
- TODO:insert into .... select .... not supported!
- all columns in group by clause should be in the selected…
AI-assisted analysis of MyCATApache/Mycat-Server@65f8d8beb7 (2026-09-11).
Data as JSON: /api/errors/338d05cc6b642642.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/io/mycat/route/parser/druid/impl/DruidLockTableParser.java:71
// 对于lock tables table1 write, table2 read类型的多表锁语句,DruidParser只能解析出table1,
// 由于多表锁在分布式场景处理逻辑繁琐,且应用场景较少,因此在此处对这种锁表语句进行拦截。
// 多表锁的语句在语义上会有",",这里以此为判断依据
String sql = rrs.getStatement();
sql = sql.replaceAll("\n", " ").replaceAll("\t", " ");
String[] stmts = SplitUtil.split(sql, ',', true);
// 如果命令中存在",",则按多表锁的语句来处理
if (stmts.length > 1) {
String tmpStmt = null;
String tmpWords[] = null;
for (int i = 1; i < stmts.length; i ++) {
tmpStmt = stmts[i];
tmpWords = SplitUtil.split(tmpStmt, ' ', true);
if (tmpWords.length==2 && ("READ".equalsIgnoreCase(tmpWords[1]) || "WRITE".equalsIgnoreCase(tmpWords[1]))) {
// 如果符合多表锁的语法,则继续,并在最后提示不能多表锁!
continue;
} else {
// 如果不符合多表锁的语法,则提示语法错误和不能多表锁!
throw new SQLNonTransientException("You have an error in your SQL syntax, don't support lock multi tables!");
}
}
LOGGER.error("can't lock multi-table");
throw new SQLNonTransientException("can't lock multi-table");
}
}
}
View on GitHub (pinned to 65f8d8beb7)