Что возможно стоит знать начинающему Spring java backend разработчику о работе с PostgreSQL
Как-то мы с Антоном из KazanExpress заметили, что Repeatable Read не всегда есть… ну точнее у нас глобально был Read Committed. И вот этот самый RR как будто пропадал в какие-то моменты. Иначе говоря: у нас есть операция, она под RR, но иногда происходит так, что эта операция выполняется в обычном RC.
В общем мы долго искали проблему, пока DBA из одной аутсорс компании не выяснили куда девается наш этот RR.
Наш доблестный Hikari pool открывал сессию и выставлял уровень изоляции RR, дальше открывалась транзакция, если сходились звезды и не хватало коннектов к БД, то pgbouncer жонглировал ими и выполнение транзакции попадало в другой коннекшн, так как pgbouncer в режиме transaction гарантирует выполнение одной транзакции на одном подключении.
То есть получалось примерно такое:
set transaction isolation level read committed; -- connection one
begin; -- connection two
update..... -- connection two
end; -- connection two
А нужно по фен-шую pgbouncer:
begin;
set transaction isolation level read committed;
update.....
end;
В такой ситуации выставление уровня изоляции будет верным.
Btw: Сергей из KazanExpress починил это у себя, пропатчив jdbc драйвер, но это специфик патч и не уверен, что его примут в кодобазу драйвера.
Тем не менее лучше знать о такой неординарной проблеме.
Кстати, у ребят из KazanExpress, есть что рассказать про использование pgbouncer + Hibernate, может они когда-то решаться на публикацию своих наработок.