| | |
| | | assertTrue(database.statements().isEmpty()); |
| | | assertEquals(3, dataSource.audit().rejectedStatements().size()); |
| | | } |
| | | |
| | | /** 加锁读以 select 开头却是真的会阻塞厂商写入,所以必须在到达驱动之前被单独拒绝。 */ |
| | | @Test |
| | | void lockingReadsAreRejectedBeforeTheyReachTheDriver() |
| | | { |
| | | FakeVendorDatabase database = new FakeVendorDatabase(); |
| | | ReadOnlyVendorDataSource dataSource = dataSourceOver(database); |
| | | for (String sql : List.of("select dev_uid from channel for update", |
| | | "select dev_uid from channel FOR SHARE", |
| | | "select dev_uid from channel lock in share mode", |
| | | "select dev_uid from channel with (updlock)", |
| | | "/* probe */ select dev_uid from channel with (tablock, holdlock)")) |
| | | { |
| | | assertTrue(ReadOnlyVendorDataSource.isQuery(sql), "加锁读仍然以查询开头:" + sql); |
| | | assertTrue(ReadOnlyVendorDataSource.containsLockingClause(sql), "应当识别为加锁读:" + sql); |
| | | assertThrows(NonQueryStatementException.class, |
| | | () -> dataSource.getConnection().prepareStatement(sql), sql); |
| | | } |
| | | assertTrue(database.statements().isEmpty(), "加锁读不得到达驱动"); |
| | | assertTrue(!ReadOnlyVendorDataSource.containsLockingClause("select dev_uid from channel")); |
| | | assertTrue(!ReadOnlyVendorDataSource.containsLockingClause("")); |
| | | } |
| | | |
| | | /** 连接超时与读取超时都必须由我们显式给出,且不得写入只读事务参数(5.5 不支持)。 */ |
| | | @Test |
| | | void vendorJdbcUrlCarriesBothTimeoutsAndNoReadOnlySessionVariable() |
| | | { |
| | | String url = NewareMysqlAdapterFactory.jdbcUrl("26.1.2.3", 3306, "bts63"); |
| | | |
| | | assertTrue(url.contains("connectTimeout="), url); |
| | | assertTrue(url.contains("socketTimeout="), url); |
| | | assertTrue(!url.contains("transaction_read_only"), url); |
| | | } |
| | | } |