Chris2018998 / beecp

A small JDBC Connection pool

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

默认配置下3.1.2升级到3.2.1使用Sqlite报错。

looly opened this issue · comments

Caused by: java.sql.SQLException: SQLite supports only TRANSACTION_SERIALIZABLE and TRANSACTION_READ_UNCOMMITTED.
	at org.sqlite.SQLiteConnection.setTransactionIsolation(SQLiteConnection.java:164)
	at cn.beecp.pool.FastConnectionPool.setDefaultOnRawConn(FastConnectionPool.java:244)

看了下源码变更,FastConnectionPool里setTransactionIsolation设置默认值失败旧版是打印warn日志,新版本直接抛出异常。

而默认的Isolation在Sqlite下不支持,导致创建连接池失败。

建议:

默认配置不应该报错,而是保留所有默认配置,保证开箱可用。

连接在归还的时候,有个复位操作,就是将默认值重新设置回连接上,正确的默认值是比较重要的事情,避免复位的时候发生异常,因此建议在初始化数据源的时候,将正确的默认值进行配置。

config.setDefaultTransactionIsolationCode(Connection.TRANSACTION_SERIALIZABLE);
或
config.setDefaultTransactionIsolationCode(Connection.TRANSACTION_READ_UNCOMMITTED);

此外看看Sqlite有没有最新驱动可以支持 Connection.TRANSACTION_READ_COMMITTED

确实,但是用户很有可能无法意识到这个问题。用户诉求是开箱即用。

hutool在BeeDSFactory中封装了BeeDataSource,为了保证“无感知”开箱即用,增加了以下逻辑,希望可以作为参考:

// since BeepCP 3.2.1,Sqlite下默认Transaction Isolation不支持,在此判断修正
if(StrUtil.containsIgnoreCase(jdbcUrl, "sqlite")){
	final int isolationCode = beeConfig.getDefaultTransactionIsolationCode();
	if(Connection.TRANSACTION_READ_UNCOMMITTED != isolationCode
			&& Connection.TRANSACTION_SERIALIZABLE != isolationCode){
		// SQLite只支持这两种事务
		beeConfig.setDefaultTransactionIsolation(TransactionIsolationLevel.LEVEL_READ_UNCOMMITTED);
		beeConfig.setDefaultTransactionIsolationCode(Connection.TRANSACTION_READ_UNCOMMITTED);
	}
}

可以看下这个issue:dromara/hutool#1597

我的建议是:在用户没有配置的情况下保持驱动默认配置,即defaultTransactionIsolationCode默认留空,用户设置了就注入给驱动,不设置就不注入。

看了下Druid和Hikari的实现,Druid的defaultTransactionIsolation默认为null(见DruidAbstractDataSource),Hikari默认也是null,见(HikariConfig的transactionIsolationName)

好的,我明白你的意思了,目前代码已经调整,默认情况下不做配置,将从第一个连接上读取并作为后续的默认值。
这里有一个临时版本(https://github.com/Chris2018998/BeeCP/blob/master/doc/temp/beecp-3.2.3.jar)可以先试一下,
周末再个发版本。

Good job !