Skip to content

Commit 697837c

Browse files
authored
feat: expose more methods from Connection in JDBC (#255)
* feat: expose more methods from Connection in JDBC More methods from the Connection API should be exposed in the Cloud Spanner JDBC Connection interface to make it easier to execute read-only transactions with specific timestamp bounds. Towards #253 * clirr: add ignored differences
1 parent 83e80fc commit 697837c

File tree

3 files changed

+225
-0
lines changed

3 files changed

+225
-0
lines changed

clirr-ignored-differences.xml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,56 @@
4242
<differenceType>8001</differenceType>
4343
<className>com/google/cloud/spanner/jdbc/UnitOfWork$UnitOfWorkState</className>
4444
</difference>
45+
46+
<!-- Expose more methods from Connection API in CloudSpannerJdbcConnection -->
47+
<difference>
48+
<differenceType>7012</differenceType>
49+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
50+
<method>com.google.cloud.spanner.connection.AutocommitDmlMode getAutocommitDmlMode()</method>
51+
</difference>
52+
<difference>
53+
<differenceType>7012</differenceType>
54+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
55+
<method>java.lang.String getOptimizerVersion()</method>
56+
</difference>
57+
<difference>
58+
<differenceType>7012</differenceType>
59+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
60+
<method>com.google.cloud.spanner.TimestampBound getReadOnlyStaleness()</method>
61+
</difference>
62+
<difference>
63+
<differenceType>7012</differenceType>
64+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
65+
<method>com.google.cloud.spanner.connection.TransactionMode getTransactionMode()</method>
66+
</difference>
67+
<difference>
68+
<differenceType>7012</differenceType>
69+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
70+
<method>boolean isInTransaction()</method>
71+
</difference>
72+
<difference>
73+
<differenceType>7012</differenceType>
74+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
75+
<method>boolean isTransactionStarted()</method>
76+
</difference>
77+
<difference>
78+
<differenceType>7012</differenceType>
79+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
80+
<method>void setAutocommitDmlMode(com.google.cloud.spanner.connection.AutocommitDmlMode)</method>
81+
</difference>
82+
<difference>
83+
<differenceType>7012</differenceType>
84+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
85+
<method>void setOptimizerVersion(java.lang.String)</method>
86+
</difference>
87+
<difference>
88+
<differenceType>7012</differenceType>
89+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
90+
<method>void setReadOnlyStaleness(com.google.cloud.spanner.TimestampBound)</method>
91+
</difference>
92+
<difference>
93+
<differenceType>7012</differenceType>
94+
<className>com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection</className>
95+
<method>void setTransactionMode(com.google.cloud.spanner.connection.TransactionMode)</method>
96+
</difference>
4597
</differences>

src/main/java/com/google/cloud/spanner/jdbc/CloudSpannerJdbcConnection.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
import com.google.cloud.spanner.AbortedException;
2020
import com.google.cloud.spanner.Mutation;
2121
import com.google.cloud.spanner.ResultSet;
22+
import com.google.cloud.spanner.TimestampBound;
23+
import com.google.cloud.spanner.connection.AutocommitDmlMode;
24+
import com.google.cloud.spanner.connection.TransactionMode;
2225
import java.sql.Connection;
2326
import java.sql.SQLException;
2427
import java.sql.Timestamp;
@@ -34,6 +37,113 @@
3437
*/
3538
public interface CloudSpannerJdbcConnection extends Connection {
3639

40+
/**
41+
* Sets the transaction mode to use for current transaction. This method may only be called when
42+
* in a transaction, and before the transaction is actually started, i.e. before any statements
43+
* have been executed in the transaction.
44+
*
45+
* @param transactionMode The transaction mode to use for the current transaction.
46+
* <ul>
47+
* <li>{@link TransactionMode#READ_ONLY_TRANSACTION} will create a read-only transaction and
48+
* prevent any changes to written to the database through this transaction. The read
49+
* timestamp to be used will be determined based on the current readOnlyStaleness
50+
* setting of this connection. It is recommended to use {@link
51+
* TransactionMode#READ_ONLY_TRANSACTION} instead of {@link
52+
* TransactionMode#READ_WRITE_TRANSACTION} when possible, as read-only transactions do
53+
* not acquire locks on Cloud Spanner, and read-only transactions never abort.
54+
* <li>{@link TransactionMode#READ_WRITE_TRANSACTION} this value is only allowed when the
55+
* connection is not in read-only mode and will create a read-write transaction. If
56+
* {@link Connection#isRetryAbortsInternally()} is <code>true</code>, each read/write
57+
* transaction will keep track of a running SHA256 checksum for each {@link ResultSet}
58+
* that is returned in order to be able to retry the transaction in case the transaction
59+
* is aborted by Spanner.
60+
* </ul>
61+
*/
62+
void setTransactionMode(TransactionMode transactionMode) throws SQLException;
63+
64+
/**
65+
* @return the transaction mode of the current transaction. This method may only be called when
66+
* the connection is in a transaction.
67+
*/
68+
TransactionMode getTransactionMode() throws SQLException;
69+
70+
/**
71+
* Sets the mode for executing DML statements in autocommit mode for this connection. This setting
72+
* is only used when the connection is in autocommit mode, and may only be set while the
73+
* transaction is in autocommit mode and not in a temporary transaction. The autocommit
74+
* transaction mode is reset to its default value of {@link AutocommitDmlMode#TRANSACTIONAL} when
75+
* autocommit mode is changed on the connection.
76+
*
77+
* @param mode The DML autocommit mode to use
78+
* <ul>
79+
* <li>{@link AutocommitDmlMode#TRANSACTIONAL} DML statements are executed as single
80+
* read-write transaction. After successful execution, the DML statement is guaranteed
81+
* to have been applied exactly once to the database
82+
* <li>{@link AutocommitDmlMode#PARTITIONED_NON_ATOMIC} DML statements are executed as
83+
* partitioned DML transactions. If an error occurs during the execution of the DML
84+
* statement, it is possible that the statement has been applied to some but not all of
85+
* the rows specified in the statement.
86+
* </ul>
87+
*/
88+
void setAutocommitDmlMode(AutocommitDmlMode mode) throws SQLException;
89+
90+
/**
91+
* @return the current {@link AutocommitDmlMode} setting for this connection. This method may only
92+
* be called on a connection that is in autocommit mode and not while in a temporary
93+
* transaction.
94+
*/
95+
AutocommitDmlMode getAutocommitDmlMode() throws SQLException;
96+
97+
/**
98+
* Sets the staleness to use for the current read-only transaction. This method may only be called
99+
* when the transaction mode of the current transaction is {@link
100+
* TransactionMode#READ_ONLY_TRANSACTION} and there is no transaction that has started, or when
101+
* the connection is in read-only and autocommit mode.
102+
*
103+
* @param staleness The staleness to use for the current but not yet started read-only transaction
104+
*/
105+
void setReadOnlyStaleness(TimestampBound staleness) throws SQLException;
106+
107+
/**
108+
* @return the read-only staleness setting for the current read-only transaction. This method may
109+
* only be called when the current transaction is a read-only transaction, or when the
110+
* connection is in read-only and autocommit mode.
111+
*/
112+
TimestampBound getReadOnlyStaleness() throws SQLException;
113+
114+
/**
115+
* Sets the query optimizer version to use for this connection.
116+
*
117+
* @param optimizerVersion The query optimizer version to use. Must be a valid optimizer version
118+
* number, the string <code>LATEST</code> or an empty string. The empty string will instruct
119+
* the connection to use the optimizer version that is defined in the environment variable
120+
* <code>SPANNER_OPTIMIZER_VERSION</code>. If no value is specified in the environment
121+
* variable, the default query optimizer of Cloud Spanner is used.
122+
*/
123+
void setOptimizerVersion(String optimizerVersion) throws SQLException;
124+
125+
/**
126+
* Gets the current query optimizer version of this connection.
127+
*
128+
* @return The query optimizer version that is currently used by this connection.
129+
*/
130+
String getOptimizerVersion() throws SQLException;
131+
132+
/**
133+
* @return <code>true</code> if this connection has a transaction (that has not necessarily
134+
* started). This method will only return false when the {@link Connection} is in autocommit
135+
* mode and no explicit transaction has been started by calling {@link
136+
* Connection#beginTransaction()}. If the {@link Connection} is not in autocommit mode, there
137+
* will always be a transaction.
138+
*/
139+
boolean isInTransaction() throws SQLException;
140+
141+
/**
142+
* @return <code>true</code> if this connection has a transaction that has started. A transaction
143+
* is automatically started by the first statement that is executed in the transaction.
144+
*/
145+
boolean isTransactionStarted() throws SQLException;
146+
37147
/**
38148
* @return the commit {@link Timestamp} of the last read/write transaction. If the last
39149
* transaction was not a read/write transaction, or a read/write transaction that did not

src/main/java/com/google/cloud/spanner/jdbc/JdbcConnection.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
import com.google.api.client.util.Preconditions;
2020
import com.google.cloud.spanner.Mutation;
2121
import com.google.cloud.spanner.SpannerException;
22+
import com.google.cloud.spanner.TimestampBound;
23+
import com.google.cloud.spanner.connection.AutocommitDmlMode;
2224
import com.google.cloud.spanner.connection.ConnectionOptions;
2325
import com.google.cloud.spanner.connection.StatementParser;
26+
import com.google.cloud.spanner.connection.TransactionMode;
2427
import com.google.common.base.Function;
2528
import com.google.common.collect.Iterators;
2629
import java.sql.Array;
@@ -74,6 +77,66 @@ public String nativeSQL(String sql) throws SQLException {
7477
.sqlWithNamedParameters;
7578
}
7679

80+
@Override
81+
public void setTransactionMode(TransactionMode mode) throws SQLException {
82+
checkClosed();
83+
getSpannerConnection().setTransactionMode(mode);
84+
}
85+
86+
@Override
87+
public TransactionMode getTransactionMode() throws SQLException {
88+
checkClosed();
89+
return getSpannerConnection().getTransactionMode();
90+
}
91+
92+
@Override
93+
public void setAutocommitDmlMode(AutocommitDmlMode mode) throws SQLException {
94+
checkClosed();
95+
getSpannerConnection().setAutocommitDmlMode(mode);
96+
}
97+
98+
@Override
99+
public AutocommitDmlMode getAutocommitDmlMode() throws SQLException {
100+
checkClosed();
101+
return getSpannerConnection().getAutocommitDmlMode();
102+
}
103+
104+
@Override
105+
public void setReadOnlyStaleness(TimestampBound staleness) throws SQLException {
106+
checkClosed();
107+
getSpannerConnection().setReadOnlyStaleness(staleness);
108+
}
109+
110+
@Override
111+
public TimestampBound getReadOnlyStaleness() throws SQLException {
112+
checkClosed();
113+
return getSpannerConnection().getReadOnlyStaleness();
114+
}
115+
116+
@Override
117+
public void setOptimizerVersion(String optimizerVersion) throws SQLException {
118+
checkClosed();
119+
getSpannerConnection().setOptimizerVersion(optimizerVersion);
120+
}
121+
122+
@Override
123+
public String getOptimizerVersion() throws SQLException {
124+
checkClosed();
125+
return getSpannerConnection().getOptimizerVersion();
126+
}
127+
128+
@Override
129+
public boolean isInTransaction() throws SQLException {
130+
checkClosed();
131+
return getSpannerConnection().isInTransaction();
132+
}
133+
134+
@Override
135+
public boolean isTransactionStarted() throws SQLException {
136+
checkClosed();
137+
return getSpannerConnection().isTransactionStarted();
138+
}
139+
77140
@Override
78141
public void setAutoCommit(boolean autoCommit) throws SQLException {
79142
checkClosed();

0 commit comments

Comments
 (0)