yeg
6 天以前 e38aca8134570513435c003c25dc05f1ae51c9c9
battery-device-neware/src/test/java/com/battery/device/neware/ReadOnlyVendorDataSourceTest.java
@@ -158,4 +158,37 @@
        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);
    }
}