Существует ли библиотека Java с открытым исходным кодом, которая добавляет поддержку XA в базы данных, которые изначально не поддерживают ее? То есть он оборачивает источник данных JDBC, отличный от XA, и заботится о необходимых коммитах/откатах за кулисами для двухэтапных коммитов?
Используете XA с базами данных, которые изначально не поддерживают его?
Ответы (1)
Нет, потому что это невозможно.
Давайте рассмотрим, для чего предназначен XA. Это согласованный протокол, гарантирующий свойства ACID для транзакций, охватывающих несколько диспетчеров ресурсов. Для этого используется двухэтапный протокол фиксации: менеджер транзакций подготавливает каждый менеджер ресурсов, а затем фиксирует каждый из них.
Чтобы протокол работал правильно, менеджер ресурсов, например. базу данных, должны дать определенные гарантии на этапе подготовки. К ним относятся: а) не делать какие-либо изменения видимыми для других процессов до фазы фиксации («Изоляция»), б) обеспечение возможности выполнения обновления во время фиксации, если это необходимо, даже в случае сбоя между подготовкой и фиксацией («Долговечность») и c) обеспечение того, чтобы данные, обрабатываемые в различных транзакциях, демонстрировали обещанные свойства согласованности. На самом деле единственный способ реализовать это - эксклюзивная блокировка. Даже менеджеры ресурсов, например. pgsql и oracle, которые используют MVCC или другие методы во время большинства операций, будут брать эксклюзивные блокировки при подготовке.
Без доступа к внутренним компонентам базы данных вы не сможете получить блокировки и удерживать их при подключении. Следовательно, вы не можете написать код, отвечающий транзакционным требованиям. Таким образом, нет необходимости размещать XA поверх механизма базы данных — его нужно «запечь».
Тем не мение...
Вы можете подделать некоторые аспекты поведения XA. В зависимости от ваших конкретных требований к приложению это может позволить создать полезное решение.
Во-первых, вы можете использовать последнюю оптимизацию ресурсов (также известную как оптимизация последней фиксации ресурсов или последний гамбит ресурсов), чтобы задействовать один не-XA, то есть однофазный ресурс, в транзакцию XA с одним или несколькими реальными ресурсами XA. Заказывая однофазный ресурс последним в порядке обработки, вы можете добиться чего-то, что ведет себя как XA для большинства сценариев. Он ужасно ломается, если сбой происходит в определенные моменты выполнения, поэтому вам нужно написать собственный код согласования данных или положиться на человека, чтобы справиться с этим непредвиденным обстоятельством. В зависимости от семантики ваших данных это может быть или не быть привлекательным вариантом.
Затем вы можете реализовать собственный драйвер, который работает так же, как семантическая репликация. Он записывает последовательность операций SQL в журнал во время подготовки, но фактически не применяет их к базе данных до фазы фиксации. Это работает для транзакционных обновлений, которые изолированы на уровне приложения, но не будет работать, если вы полагаетесь на базу данных для управления параллелизмом за вас. Например, вы можете обнаружить, что фиксация не удалась, потому что что-то еще прокралось в конфликтующее обновление между фазами подготовки и фиксации. Вы можете использовать внешний менеджер блокировок, но только в том случае, если ваш собственный драйвер — это единственное, что общается с db. Как только появляется клиент, который не знает об этом диспетчере блокировок, все ставки снимаются.
Наконец, вы можете инвертировать эту модель и использовать транзакции на основе компенсации в рамках XA. В этой модели вы применяете обновления во время подготовки и при необходимости применяете дополнительные операции, чтобы отменить их действие на этапе отката. У этого есть два недостатка: параллельные операции могут считывать и работать с преждевременно зафиксированными значениями tx, которые позже откатываются, поскольку между подготовкой и фиксацией нет изоляции; также в зависимости от бизнес-логики нелегко генерировать подходящие заявления о компенсации. Даже если вы можете, вам нужно довольно много сложной сантехники, чтобы обеспечить их правильную работу даже в сценариях сбоя.
На самом деле вы, вероятно, ограничены LRCO, который поддерживается большинством менеджеров транзакций. Другие варианты требуют значительного опыта работы с транзакциями, а накладные расходы на разработку/тестирование обычно неоправданны. Если LRCO вам не подходит, то, честно говоря, вам будет проще изменить дизайн вашего приложения, чтобы избежать необходимости в XA.