Если экземпляр BasicDataSource
из Apache commons-dbcp (версии 1.4, т. к. я ограничен Java 1.6) сконфигурирован с defaultAutoCommit=false
, то библиотека выполняет два идиотских ROLLBACK
'а — один при взятии соединения из пула, и ещё один при возвращении его обратно (т. е. закрытии соединения из пула при сохранении низкоуровневого физического соединения открытым).
Соответствующие стек-трейсы (на примере T4CConnection
драйвера Oracle Thin):
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
(вместо единственного ROLLBACK
'а).
Вышеописанное поведение даёт дополнительную нагрузку на redo- и undo-подсистемы (что очень хорошо видно под нагрузкой в Oracle, но, на самом деле, при использовании commons-dbcp проблема универсальна — я наблюдал ровно то же самое для MySQL).
Вопрос 1: как избавиться от пресловутых ROLLBACK
'ов, сохранив экземпляр DataSource
сконфигурированным с defaultAutoCommit=false
(т. е. без необходимости вручную вызывать setAutoCommit(false)
для каждого соединения, взятого из пула)?
Вопрос 2: как можно обойти проблему средствами Oracle (т. е. без необходимости менять прикладной код или библиотеки)?