LINUX.ORG.RU

Дополнительные (бесполезные) ROLLBACK'и при использовании BasicDataSource из commons-dbcp

 , ,


0

1

Если экземпляр 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	

Т. обр., каждая успешная транзакция — это последовательность след. вида:

  1. ROLLBACK
  2. полезная работа с БД
  3. COMMIT
  4. ROLLBACK

(вместо единственного COMMIT'а), в то время как каждая неудачная — это:

  1. ROLLBACK
  2. полезная работа с БД
  3. ROLLBACK
  4. ROLLBACK

(вместо единственного ROLLBACK'а).

Вышеописанное поведение даёт дополнительную нагрузку на redo- и undo-подсистемы (что очень хорошо видно под нагрузкой в Oracle, но, на самом деле, при использовании commons-dbcp проблема универсальна — я наблюдал ровно то же самое для MySQL).

Вопрос 1: как избавиться от пресловутых ROLLBACK'ов, сохранив экземпляр DataSource сконфигурированным с defaultAutoCommit=false (т. е. без необходимости вручную вызывать setAutoCommit(false) для каждого соединения, взятого из пула)?

Вопрос 2: как можно обойти проблему средствами Oracle (т. е. без необходимости менять прикладной код или библиотеки)?

★★★

Ответ на: комментарий от Bass

А вообще я не уверен, что лишний rollback на коннекте афектит сильно производительность. По идее он прост проверяет, что транзакция уже закрыта (или не открыта) и всё.

anonymous ()
Ответ на: комментарий от anonymous

А вообще я не уверен, что лишний rollback на коннекте афектит сильно производительность. По идее он прост проверяет, что транзакция уже закрыта (или не открыта) и всё.

Всё верно. Я придерживался того же мнения.

Пока не выяснилось, что на Oracle Exadata

where query completion time is 10 times faster, even in a huge data warehouse. (C)

100500 подобных клиентов, выполняющих охулиард ROLLBACK'ов в секунду, здорово просаживают производительность.

Bass ★★★ ()
Ответ на: комментарий от Legioner

А зачем использовать этот commons dbcp? Пул есть в оракловом драйвере, его и используйте.

Затем, что Oracle — не единственная реляционная БД на свете. Увы.

Bass ★★★ ()
Ответ на: комментарий от Bass

Затем, что Oracle — не единственная реляционная БД на свете. Увы.

И вдруг настанет ненастный день после дождичка в четверг, когда будет решено мигрировать на PostgreSQL, и вот тут то и проявится вся мощь архитектуры!!1

azelipupenko ()
Ответ на: комментарий от azelipupenko

И вдруг настанет ненастный день после дождичка в четверг, когда будет решено мигрировать на PostgreSQL, и вот тут то и проявится вся мощь архитектуры!!1

Типа, йумар такой.

Дружище, решение *уже* работает на практически любой БД, от Apache Derby до Sybase.

Bass ★★★ ()
Ответ на: комментарий от Bass

Дружище, решение *уже* работает на практически любой БД, от Apache Derby до Sybase.

Да, да, в параллельных вселенных. По факту же, твоё решение работает на одной СУБД. И будет работать на ней же. Никаких миграций не будет. Будет только лишний слой абстракции со своими багами и причудами, о которых ты любезно поведал. Лол.

azelipupenko ()
Ответ на: комментарий от Bass

Затем, что Oracle — не единственная реляционная БД на свете. Увы.

Как connection pool этот apache dbcp очень сильно не любят, он один из самых медленных, например spring-boot сразу идет с зависимостями на HikariCP.

Aber ★★ ()
Ответ на: комментарий от orm-i-auga

Форкнуть?

Возможно. Иногда приходится, да. Ту же HSQL таки пришлось форкнуть из-за невменяемости (единственного) разработчика и отсутствия процесса.

Bass ★★★ ()
Ответ на: комментарий от Bass

Если у вас код прибит к реализации пула, то что-то в вашей архитектуре не так.

ps. в этом пуле (не помню какой версии) были глобальные блокировки, отчего он очень любил вставать колом и элегантно вешать весь сервер. Вроде из-за этого его форкнули ребята из томката.

subwoofer ★★★★★ ()
Ответ на: комментарий от subwoofer

Если у вас код прибит к реализации пула, то что-то в вашей архитектуре не так.

Часть кода — безусловно. Это legacy, увы. Кишки тянутся ещё с конца 90-х.

ps. в этом пуле (не помню какой версии) были глобальные блокировки, отчего он очень любил вставать колом и элегантно вешать весь сервер. Вроде из-за этого его форкнули ребята из томката.

Спасибо за наводку. Дойдут руки — раскопаю.

Bass ★★★ ()