如果来自 Apache commons-dbcp 的BasicDataSource
(版本1.4,因为我仅限于Java 1.6)配置了defaultAutoCommit=false
,则另外两个{{1} }被执行,一个从池中建立数据库连接时执行,另一个在返回池中连接时执行。
相应的堆栈跟踪为( Oracle Thin 的ROLLBACK
示例):
T4CConnection
和
T4CConnection(PhysicalConnection).rollback() line: 1950
PoolableConnection(DelegatingConnection).rollback() line: 368
PoolableConnectionFactory.passivateObject(Object) line: 685
BasicDataSource.validateConnectionFactory(PoolableConnectionFactory) line: 1559
BasicDataSource.createPoolableConnectionFactory(ConnectionFactory, KeyedObjectPoolFactory, AbandonedConfig) line: 1545
BasicDataSource.createDataSource() line: 1388
BasicDataSource.getConnection() line: 1044
因此,每个成功的数据库事务都是以下序列:
T4CConnection(PhysicalConnection).rollback() line: 1950
PoolableConnection(DelegatingConnection).rollback() line: 368
PoolableConnectionFactory.passivateObject(Object) line: 685
GenericObjectPool.addObjectToPool(Object, boolean) line: 1379
GenericObjectPool.returnObject(Object) line: 1342
PoolableConnection.close() line: 90
PoolingDataSource$PoolGuardConnectionWrapper.close() line: 191
ROLLBACK
COMMIT
(而不是单个ROLLBACK
),而每个失败的则是一个序列
COMMIT
ROLLBACK
ROLLBACK
(而不是单个ROLLBACK
)。
此行为对重做和撤消子系统(特别是在 Oracle 情况下)施加了额外的压力,但是该问题对于通过 commons-dbcp 访问的任何数据库均有效。 :我在 MySQL 上也观察到了同样的问题。
如何在仍将数据源配置为ROLLBACK
的情况下摆脱这些多余的ROLLBACK
(即,无需为从连接中获取的每个连接手动调用defaultAutoCommit=false
数据源)?
或者,如何从 Oracle 方面缓解问题(即,无需更改代码或替换库)?