diff --git a/jdbc/src/main/java/tech/ydb/jdbc/context/TableTxExecutor.java b/jdbc/src/main/java/tech/ydb/jdbc/context/TableTxExecutor.java index a6834ae..c10bb87 100644 --- a/jdbc/src/main/java/tech/ydb/jdbc/context/TableTxExecutor.java +++ b/jdbc/src/main/java/tech/ydb/jdbc/context/TableTxExecutor.java @@ -87,10 +87,20 @@ public void rollback(YdbContext ctx, YdbValidator validator) throws SQLException @Override public YdbQueryResult executeDataQuery(YdbStatement statement, YdbQuery query, String preparedYql, Params params, long timeout, boolean keepInCache) throws SQLException { - YdbQueryResult result = super.executeDataQuery(statement, query, preparedYql, params, timeout, keepInCache); - isWriteTx = isInsideTransaction() && (isWriteTx || query.isWriting()); + try { + YdbQueryResult result = super.executeDataQuery(statement, query, preparedYql, params, timeout, keepInCache); + isWriteTx = isInsideTransaction() && (isWriteTx || query.isWriting()); + return result; + } catch (YdbConditionallyRetryableException ex) { + if (isAutoCommit()) { + throw ex; + } - return result; + Status status = Status.of(StatusCode.ABORTED).withCause(ex); + throw ExceptionFactory.createException("Data query wasn't executed", + new UnexpectedResultException(ex.getMessage(), status) + ); + } } @Override diff --git a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverStaticCredsTest.java b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverStaticCredsTest.java index e96d150..6e266da 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverStaticCredsTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverStaticCredsTest.java @@ -9,7 +9,6 @@ import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -22,7 +21,6 @@ * * @author Aleksandr Gorshenin */ -@Disabled public class YdbDriverStaticCredsTest { @RegisterExtension private static final YdbHelperExtension ydb = new YdbHelperExtension(); @@ -38,7 +36,9 @@ public static void createUsers() throws SQLException { statement.execute("" + "CREATE USER user1 PASSWORD NULL;\n" + "CREATE USER user2 PASSWORD 'pwss';\n" - + "CREATE USER user3 PASSWORD 'pw :ss;'\n;" + + "CREATE USER user3 PASSWORD 'pwss';\n" + + "CREATE USER user4 PASSWORD 'pw@&ss'\n;" + + "CREATE USER user5 PASSWORD 'pw@&ss'\n;" ); } } @@ -46,7 +46,7 @@ public static void createUsers() throws SQLException { @AfterAll public static void dropUsers() throws SQLException { try (Statement statement = jdbc.connection().createStatement()) { - statement.execute("DROP USER IF EXISTS user1, user2, user3;"); + statement.execute("DROP USER IF EXISTS user1, user2, user3, user4, user5;"); } } @@ -91,10 +91,10 @@ public void connectOK() throws SQLException { testConnection(connectByAuthority("user1", null), "user1"); testConnection(connectByProperties("user2", "pwss"), "user2"); - testConnection(connectByAuthority("user2", "pwss"), "user2"); + testConnection(connectByAuthority("user3", "pwss"), "user3"); - testConnection(connectByProperties("user3", "pw :ss;"), "user3"); - testConnection(connectByAuthority("user3", "pw :ss;"), "user3"); + testConnection(connectByProperties("user4", "pw@&ss"), "user4"); + testConnection(connectByAuthority("user5", "pw@&ss"), "user5"); } @Test @@ -106,17 +106,17 @@ public void connectWrong() throws SQLException { wrongConnection(connectByProperties("user2", null)); wrongConnection(connectByProperties("user2", "pass")); - wrongConnection(connectByAuthority("user2", "")); - wrongConnection(connectByAuthority("user2", null)); - wrongConnection(connectByAuthority("user2", "pass")); - - wrongConnection(connectByProperties("user3", "")); - wrongConnection(connectByProperties("user3", null)); - wrongConnection(connectByProperties("user3", "pw:ss;")); - wrongConnection(connectByAuthority("user3", "")); wrongConnection(connectByAuthority("user3", null)); - wrongConnection(connectByAuthority("user3", "pw:ss;")); + wrongConnection(connectByAuthority("user3", "pass")); + + wrongConnection(connectByProperties("user4", "")); + wrongConnection(connectByProperties("user4", null)); + wrongConnection(connectByProperties("user4", "pw:ss;")); + + wrongConnection(connectByAuthority("user5", "")); + wrongConnection(connectByAuthority("user5", null)); + wrongConnection(connectByAuthority("user5", "pw:@&ss")); } interface ConnectionSupplier { diff --git a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverTxValidateTest.java b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverTxValidateTest.java index 6ccc5d5..cb73e03 100644 --- a/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverTxValidateTest.java +++ b/jdbc/src/test/java/tech/ydb/jdbc/YdbDriverTxValidateTest.java @@ -18,6 +18,9 @@ import tech.ydb.core.StatusCode; import tech.ydb.core.UnexpectedResultException; import tech.ydb.jdbc.context.YdbContext; +import tech.ydb.jdbc.context.YdbExecutor; +import tech.ydb.jdbc.exception.YdbConditionallyRetryableException; +import tech.ydb.jdbc.exception.YdbRetryableException; import tech.ydb.jdbc.impl.YdbTracerImpl; import tech.ydb.jdbc.impl.helper.ExceptionAssert; import tech.ydb.jdbc.impl.helper.JdbcConnectionExtention; @@ -153,6 +156,52 @@ public void commitedTxTest() throws SQLException { } } + @Test + public void executeDataQueryTest() throws SQLException { + String url = jdbcURL.withArg("withTxValidationTable", "tx1_store").build(); + try (Connection conn = DriverManager.getConnection(url)) { + ErrorTxTracer tracer = YdbTracerImpl.use(new ErrorTxTracer()); + // table was created automatically + assertTxCount("tx1_store", 0); + + conn.setAutoCommit(true); + try (Statement st = conn.createStatement()) { + st.execute("DELETE FROM tx1_store"); + + tracer.throwErrorOn("<-- Status", Status.of(StatusCode.UNDETERMINED)); + YdbConditionallyRetryableException e = Assertions.assertThrows(YdbConditionallyRetryableException.class, + () -> st.execute("DELETE FROM tx1_store")); + Assertions.assertEquals(Status.of(StatusCode.UNDETERMINED), e.getStatus()); + + tracer.throwErrorOn("<-- Status", Status.of(StatusCode.ABORTED)); + YdbRetryableException e2 = Assertions.assertThrows(YdbRetryableException.class, + () -> st.execute("DELETE FROM tx1_store")); + Assertions.assertEquals(Status.of(StatusCode.ABORTED), e2.getStatus()); + } + + + conn.setAutoCommit(false); + try (Statement st = conn.createStatement()) { + YdbExecutor executor = st.unwrap(YdbStatement.class).getConnection().getExecutor(); + st.execute("DELETE FROM tx1_store"); + conn.commit(); + + tracer.throwErrorOn("<-- Status", Status.of(StatusCode.UNDETERMINED)); + YdbRetryableException e = Assertions.assertThrows(YdbRetryableException.class, + () -> st.execute("DELETE FROM tx1_store")); + Assertions.assertEquals(StatusCode.ABORTED, e.getStatus().getCode()); + Assertions.assertNotNull(e.getStatus().getCause()); + + tracer.throwErrorOn("<-- Status", Status.of(StatusCode.ABORTED)); + YdbRetryableException e2 = Assertions.assertThrows(YdbRetryableException.class, + () -> st.execute("DELETE FROM tx1_store")); + Assertions.assertEquals(Status.of(StatusCode.ABORTED), e2.getStatus()); + } + } finally { + jdbc.connection().createStatement().execute("DROP TABLE tx1_store"); + } + } + @Test public void invalididTxTableTest() throws SQLException { String url = jdbcURL.withArg("withTxValidationTable", "tx store").build();