feat(mcp): execute sql batches with opt-in rollbackable transactions

This commit is contained in:
Abeautifulsnow authored and GitHub committed 2026-09-04 13:43:06 +08:00
1 parent 7390ac109c
commit 543bf66905
18 files changed
+2496 -219

No files matched your search

@@ -56,8 +56,9 @@ public final class TransactionExecutor {
return unchecked(() -> {
long start = System.currentTimeMillis();
if (!supportsTransactions(conn)) {
long totalAffected = executeAll(conn, statements, schema, setSchemaSql, resetSchemaSql, runner);
return result(totalAffected, start);
// An explicit transaction request must not degrade to auto-commit:
// callers rely on it to avoid partial writes when a later statement fails.
throw new UnsupportedOperationException("Transactions are not supported by this JDBC driver");
}
boolean savedAutoCommit = conn.getAutoCommit();
@@ -626,17 +626,19 @@ class CommonJavaCompatibilityTest {
}
@Test
void executesTransactionsOneByOneWhenJdbcDriverDoesNotSupportTransactions() {
void rejectsTransactionsWhenJdbcDriverDoesNotSupportTransactions() {
List<String> calls = new ArrayList<>();
DatabaseAgent agent = new TransactionAgent(nonTransactionalConnection(calls));
QueryResult result = agent.executeTransaction(Arrays.asList("UPDATE A SET ID = 1", "UPDATE B SET ID = 2"), "APP");
assertEquals(2L, result.getAffected_rows());
assertEquals(
Arrays.asList("supportsTransactions", "execute:SET SCHEMA \"APP\"", "executeUpdate:UPDATE A SET ID = 1", "executeUpdate:UPDATE B SET ID = 2"),
calls
UnsupportedOperationException error = assertThrows(
UnsupportedOperationException.class,
() -> agent.executeTransaction(Arrays.asList("UPDATE A SET ID = 1", "UPDATE B SET ID = 2"), "APP")
);
assertEquals("Transactions are not supported by this JDBC driver", error.getMessage());
// Capability is checked before schema switching or statements, so a
// failed transaction request cannot leave a partially applied batch.
assertEquals(Collections.singletonList("supportsTransactions"), calls);
}
@Test