Skip to content

Commit 6f15fd1

Browse files
Flip IgnoreTransactions default from 0 to 1 for multi-statement transaction preview (#1176)
## Summary - Changes default value of `IgnoreTransactions` parameter from `0` to `1`, making transactions disabled by default - Updates `supportsTransactions()` to respect the `IgnoreTransactions` flag, returning `false` when transactions are ignored (default) and `true` when explicitly enabled - Adds test case for when transactions are explicitly enabled via `IgnoreTransactions=0` ## Background The multi-statement transaction feature is currently in private preview for limited workspaces. When BI tools (Tableau, Power BI, DBeaver) detect transaction support via `supportsTransactions()`, they automatically use transaction methods, causing failures for customers not enrolled in the preview. This change prevents unexpected failures for non-preview customers while allowing preview participants to opt-in by explicitly setting `IgnoreTransactions=0` in their connection string. ## Migration Path - **Non-preview customers**: No action required - transactions are now disabled by default - **Preview participants**: Set `IgnoreTransactions=0` in connection string to enable transaction support - **GA migration**: When multi-statement transactions reach GA, flip the default back to `0` ## Test plan - [ ] Verify existing tests pass - [ ] Verify default connection returns `supportsTransactions() = false` - [ ] Verify connection with `IgnoreTransactions=0` returns `supportsTransactions() = true` - [ ] Verify transaction methods (`setAutoCommit`, `commit`, `rollback`) are no-ops by default 🤖 Generated with [Claude Code](https://claude.com/claude-code) Signed-off-by: Vikrant Puppala <vikrant.puppala@databricks.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 21e07bd commit 6f15fd1

6 files changed

Lines changed: 42 additions & 21 deletions

File tree

NEXT_CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- Added token caching for all authentication providers to reduce token endpoint calls.
77

88
### Updated
9+
- Changed default value of `IgnoreTransactions` from `0` to `1` to disable multi-statement transactions by default. Preview participants can opt-in by setting `IgnoreTransactions=0`. Also updated `supportsTransactions()` to respect this flag.
910

1011
### Fixed
1112

src/main/java/com/databricks/jdbc/api/impl/DatabricksConnectionContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,7 @@ public boolean isBatchedInsertsEnabled() {
11641164

11651165
@Override
11661166
public boolean getIgnoreTransactions() {
1167-
return getParameter(DatabricksJdbcUrlParams.IGNORE_TRANSACTIONS, "0").equals("1");
1167+
return getParameter(DatabricksJdbcUrlParams.IGNORE_TRANSACTIONS).equals("1");
11681168
}
11691169

11701170
@Override

src/main/java/com/databricks/jdbc/api/impl/DatabricksDatabaseMetaData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -834,7 +834,7 @@ public int getDefaultTransactionIsolation() throws SQLException {
834834
public boolean supportsTransactions() throws SQLException {
835835
LOGGER.debug("public boolean supportsTransactions()");
836836
throwExceptionIfConnectionIsClosed();
837-
return true;
837+
return !session.getConnectionContext().getIgnoreTransactions();
838838
}
839839

840840
@Override

src/main/java/com/databricks/jdbc/common/DatabricksJdbcUrlParams.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public enum DatabricksJdbcUrlParams {
169169
"EnableSQLValidationForIsValid",
170170
"Enable SQL query execution for connection validation in isValid() method",
171171
"0"),
172-
IGNORE_TRANSACTIONS("IgnoreTransactions", "Ignore transaction-related method calls", "0"),
172+
IGNORE_TRANSACTIONS("IgnoreTransactions", "Ignore transaction-related method calls", "1"),
173173
FETCH_AUTOCOMMIT_FROM_SERVER(
174174
"FetchAutoCommitFromServer",
175175
"Fetch auto-commit state from server using SQL query instead of using cached value",

src/test/java/com/databricks/jdbc/api/impl/DatabricksConnectionTest.java

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ public class DatabricksConnectionTest {
6161
.collect(Collectors.joining(";")));
6262
private static final String IGNORE_TRANSACTIONS_JDBC_URL =
6363
"jdbc:databricks://sample-host.18.azuredatabricks.net:4423/default;transportMode=http;ssl=1;AuthMech=3;httpPath=/sql/1.0/warehouses/99999999;IgnoreTransactions=1";
64+
private static final String TRANSACTIONS_ENABLED_JDBC_URL =
65+
String.format(
66+
"jdbc:databricks://sample-host.18.azuredatabricks.net:4423/%s;transportMode=http;ssl=1;AuthMech=3;httpPath=/sql/1.0/warehouses/99999999;ConnCatalog=%s;ConnSchema=%s;logLevel=FATAL;IgnoreTransactions=0",
67+
SCHEMA, CATALOG, SCHEMA);
6468
private static final ImmutableSessionInfo IMMUTABLE_SESSION_INFO =
6569
ImmutableSessionInfo.builder().computeResource(warehouse).sessionId(SESSION_ID).build();
6670
@Mock DatabricksSdkClient databricksClient;
@@ -69,11 +73,14 @@ public class DatabricksConnectionTest {
6973
private static DatabricksConnection connection;
7074

7175
private static IDatabricksConnectionContext connectionContext;
76+
private static IDatabricksConnectionContext transactionsEnabledContext;
7277

7378
@BeforeAll
7479
static void setup() throws DatabricksSQLException {
7580
connectionContext =
7681
DatabricksConnectionContext.parse(CATALOG_SCHEMA_JDBC_URL, new Properties());
82+
transactionsEnabledContext =
83+
DatabricksConnectionContext.parse(TRANSACTIONS_ENABLED_JDBC_URL, new Properties());
7784
}
7885

7986
@Test
@@ -441,9 +448,9 @@ void testUnsupportedOperations() throws SQLException {
441448
ResultSet.CONCUR_READ_ONLY,
442449
ResultSet.CLOSE_CURSORS_AT_COMMIT);
443450
});
444-
assertThrows(
445-
DatabricksSQLFeatureNotImplementedException.class, () -> connection.setSavepoint("1"));
446-
assertThrows(DatabricksSQLFeatureNotImplementedException.class, connection::setSavepoint);
451+
// With default IgnoreTransactions=1, savepoint methods return null (no-op)
452+
assertNull(connection.setSavepoint("1"));
453+
assertNull(connection.setSavepoint());
447454
assertThrows(DatabricksSQLFeatureNotImplementedException.class, connection::createClob);
448455
assertThrows(DatabricksSQLFeatureNotImplementedException.class, connection::createBlob);
449456
assertThrows(DatabricksSQLFeatureNotImplementedException.class, connection::createNClob);
@@ -454,10 +461,9 @@ void testUnsupportedOperations() throws SQLException {
454461
assertThrows(
455462
DatabricksSQLFeatureNotSupportedException.class,
456463
() -> connection.prepareStatement(SQL, new String[0]));
457-
assertThrows(
458-
DatabricksSQLFeatureNotImplementedException.class, () -> connection.rollback(null));
459-
assertThrows(
460-
DatabricksSQLFeatureNotImplementedException.class, () -> connection.releaseSavepoint(null));
464+
// With default IgnoreTransactions=1, these are no-ops
465+
assertDoesNotThrow(() -> connection.rollback(null));
466+
assertDoesNotThrow(() -> connection.releaseSavepoint(null));
461467
assertThrows(
462468
DatabricksSQLFeatureNotSupportedException.class,
463469
() -> connection.setNetworkTimeout(null, 1));
@@ -646,7 +652,7 @@ public void testSetAutoCommitToFalse() throws SQLException {
646652
when(databricksClient.createSession(
647653
new Warehouse(WAREHOUSE_ID), CATALOG, SCHEMA, new HashMap<>()))
648654
.thenReturn(IMMUTABLE_SESSION_INFO);
649-
connection = new DatabricksConnection(connectionContext, databricksClient);
655+
connection = new DatabricksConnection(transactionsEnabledContext, databricksClient);
650656
connection.open();
651657

652658
DatabricksConnection spyConnection = spy(connection);
@@ -671,7 +677,7 @@ public void testSetAutoCommitToTrue() throws SQLException {
671677
when(databricksClient.createSession(
672678
new Warehouse(WAREHOUSE_ID), CATALOG, SCHEMA, new HashMap<>()))
673679
.thenReturn(IMMUTABLE_SESSION_INFO);
674-
connection = new DatabricksConnection(connectionContext, databricksClient);
680+
connection = new DatabricksConnection(transactionsEnabledContext, databricksClient);
675681
connection.open();
676682

677683
DatabricksConnection spyConnection = spy(connection);
@@ -697,7 +703,7 @@ public void testSetAutoCommitWithServerError() throws SQLException {
697703
when(databricksClient.createSession(
698704
new Warehouse(WAREHOUSE_ID), CATALOG, SCHEMA, new HashMap<>()))
699705
.thenReturn(IMMUTABLE_SESSION_INFO);
700-
connection = new DatabricksConnection(connectionContext, databricksClient);
706+
connection = new DatabricksConnection(transactionsEnabledContext, databricksClient);
701707
connection.open();
702708

703709
DatabricksConnection spyConnection = spy(connection);
@@ -744,7 +750,7 @@ public void testCommitSuccess() throws SQLException {
744750
when(databricksClient.createSession(
745751
new Warehouse(WAREHOUSE_ID), CATALOG, SCHEMA, new HashMap<>()))
746752
.thenReturn(IMMUTABLE_SESSION_INFO);
747-
connection = new DatabricksConnection(connectionContext, databricksClient);
753+
connection = new DatabricksConnection(transactionsEnabledContext, databricksClient);
748754
connection.open();
749755

750756
DatabricksConnection spyConnection = spy(connection);
@@ -785,7 +791,7 @@ public void testCommitWithServerError() throws SQLException {
785791
when(databricksClient.createSession(
786792
new Warehouse(WAREHOUSE_ID), CATALOG, SCHEMA, new HashMap<>()))
787793
.thenReturn(IMMUTABLE_SESSION_INFO);
788-
connection = new DatabricksConnection(connectionContext, databricksClient);
794+
connection = new DatabricksConnection(transactionsEnabledContext, databricksClient);
789795
connection.open();
790796

791797
DatabricksConnection spyConnection = spy(connection);
@@ -812,7 +818,7 @@ public void testRollbackSuccess() throws SQLException {
812818
when(databricksClient.createSession(
813819
new Warehouse(WAREHOUSE_ID), CATALOG, SCHEMA, new HashMap<>()))
814820
.thenReturn(IMMUTABLE_SESSION_INFO);
815-
connection = new DatabricksConnection(connectionContext, databricksClient);
821+
connection = new DatabricksConnection(transactionsEnabledContext, databricksClient);
816822
connection.open();
817823

818824
DatabricksConnection spyConnection = spy(connection);
@@ -853,7 +859,7 @@ public void testRollbackWithServerError() throws SQLException {
853859
when(databricksClient.createSession(
854860
new Warehouse(WAREHOUSE_ID), CATALOG, SCHEMA, new HashMap<>()))
855861
.thenReturn(IMMUTABLE_SESSION_INFO);
856-
connection = new DatabricksConnection(connectionContext, databricksClient);
862+
connection = new DatabricksConnection(transactionsEnabledContext, databricksClient);
857863
connection.open();
858864

859865
DatabricksConnection spyConnection = spy(connection);
@@ -879,7 +885,7 @@ public void testTransactionMethodsPreserveExceptionChain() throws SQLException {
879885
when(databricksClient.createSession(
880886
new Warehouse(WAREHOUSE_ID), CATALOG, SCHEMA, new HashMap<>()))
881887
.thenReturn(IMMUTABLE_SESSION_INFO);
882-
connection = new DatabricksConnection(connectionContext, databricksClient);
888+
connection = new DatabricksConnection(transactionsEnabledContext, databricksClient);
883889
connection.open();
884890

885891
DatabricksConnection spyConnection = spy(connection);
@@ -1059,8 +1065,9 @@ public void testSetAutoCommitSkipsServerCallWhenAlreadyFalse() throws SQLExcepti
10591065

10601066
@Test
10611067
public void testSetAutoCommitDoesNotSkipWithFetchFromServerEnabled() throws SQLException {
1062-
// Create connection with FetchAutoCommitFromServer=1
1063-
String urlWithFetch = CATALOG_SCHEMA_JDBC_URL + ";FetchAutoCommitFromServer=1";
1068+
// Create connection with FetchAutoCommitFromServer=1 and IgnoreTransactions=0
1069+
String urlWithFetch =
1070+
CATALOG_SCHEMA_JDBC_URL + ";FetchAutoCommitFromServer=1;IgnoreTransactions=0";
10641071
IDatabricksConnectionContext contextWithFetch =
10651072
DatabricksConnectionContext.parse(urlWithFetch, new Properties());
10661073

src/test/java/com/databricks/jdbc/api/impl/DatabricksDatabaseMetaDataTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,20 @@ public void getDefaultTransactionIsolation_returnsExpectedIsolationLevel() throw
438438
}
439439

440440
@Test
441-
public void supportsTransactions_returnsFalse() throws Exception {
441+
public void supportsTransactions_returnsFalseByDefault() throws Exception {
442+
// Default IgnoreTransactions=1 means transactions are ignored, so supportsTransactions returns
443+
// false
444+
boolean supportsTransactions = metaData.supportsTransactions();
445+
assertFalse(supportsTransactions);
446+
}
447+
448+
@Test
449+
public void supportsTransactions_returnsTrueWhenTransactionsEnabled() throws Exception {
450+
// When IgnoreTransactions=0, transactions are enabled, so supportsTransactions returns true
451+
String urlWithTransactionsEnabled = WAREHOUSE_JDBC_URL + ";IgnoreTransactions=0";
452+
when(session.getConnectionContext())
453+
.thenReturn(
454+
DatabricksConnectionContext.parse(urlWithTransactionsEnabled, new Properties()));
442455
boolean supportsTransactions = metaData.supportsTransactions();
443456
assertTrue(supportsTransactions);
444457
}

0 commit comments

Comments
 (0)