fix(navicat): clarify stateless tunnel transaction errors (#13073)

* fix(navicat): allow backup transactions through HTTP tunnel

* style(navicat): format tunnel source for CI

* style(navicat): match CI rustfmt output

* fix(transfer): complete Oracle transfer test request

* Revert "fix(navicat): allow backup transactions through HTTP tunnel"

This reverts commit ed147aced7.

* fix(navicat): clarify stateless transaction boundary
This commit is contained in:
Elias authored and GitHub committed 2026-10-21 22:27:06 +08:00
1 parent b9563ee439
commit e302a8398b
2 files changed
+15 -5

No files matched your search

@@ -289,7 +289,7 @@ fn validate_stateless_query(sql: &str) -> Result<(), String> {
}));
if transaction {
return Err(
"Transactions and autocommit settings are not supported by Navicat HTTP tunnels: each request uses a separate MySQL session"
"Transactions, autocommit settings, and consistent snapshots are not supported by the stateless Navicat HTTP tunnel; use the DBX TCP HTTP tunnel (dbx_tunnel.php) for a fixed database session"
.to_string(),
);
}
@@ -684,7 +684,9 @@ mod tests {
let response = send_test_command(&mut client, 0x03, sql.as_bytes()).await;
assert_eq!(response[0], 0xff, "{sql}");
assert_eq!(u16::from_le_bytes(response[1..3].try_into().unwrap()), 1235, "{sql}");
assert!(String::from_utf8_lossy(&response[9..]).contains("separate MySQL session"));
let message = String::from_utf8_lossy(&response[9..]);
assert!(message.contains("stateless Navicat HTTP tunnel"), "{sql}: {message}");
assert!(message.contains("fixed database session"), "{sql}: {message}");
}
assert!(tokio::time::timeout(std::time::Duration::from_millis(50), http_listener.accept()).await.is_err());
assert_eq!(send_test_command(&mut client, 0x0e, b"").await[0], 0);
+11 -3
View File
@@ -23,6 +23,14 @@ can change a POST request into a GET.
This protocol supports regular queries, `USE`, ping, and disconnect. MySQL TLS
and prepared statements are not supported by the Navicat HTTP tunnel protocol.
Each HTTP request opens a separate MySQL session. Transactions (including manual
transactions and consistent backup snapshots), savepoints, and autocommit
settings are rejected before any SQL is sent to the PHP host.
Each HTTP request opens a separate MySQL session, so this endpoint is appropriate
only for non-transactional operations and backups that do not request a consistent
snapshot. Transactions, savepoints, autocommit settings, and consistent-snapshot
backup sequences are rejected before any SQL is sent to the PHP host; this prevents
a successful-looking `ROLLBACK` from failing to undo a write that ran in another
session.
For transaction workflows or backups that require a consistent snapshot, deploy
DBX's own `deploy/dbx_tunnel.php` endpoint instead. That endpoint keeps one
database TCP session alive for the lifetime of the tunnel and is configured as the
DBX TCP HTTP tunnel, not as the Navicat-compatible endpoint.