Запись JPA из нескольких процессов в одну БД - PullRequest
1 голос
/ 10 июля 2009

Итак, у меня есть вопрос дизайна: у меня запущено несколько процессов, которые обновляют мою базу данных. В качестве примера представим банковскую систему, в которой я записываю переводы с одного счета на другой. В этом случае я должен вычесть сумму перевода из исходного счета и зачислить на целевой счет ту же сумму, что и отдельная транзакция.

Я хотел бы быть абсолютно уверенным, что нет условий, в которых мои транзакции могли бы быть повреждены, поэтому я изначально думал о пессимистической блокировке исходной и целевой учетных записей, пока я делаю вычисления и фиксирую изменения. Из того, что я читал в Интернете о JPA, кажется, что пессимистическая блокировка не всегда поддерживается (по крайней мере, не напрямую).

Может ли кто-нибудь дать мне представление о других способах обеспечения целостности моих транзакций в нескольких процессах?

Любая помощь / указатели с благодарностью.

Спасибо ...

- Стив

1 Ответ

2 голосов
/ 10 июля 2009

Предпочтительным способом блокировки в системе, которая использует отдельное постоянство (например, JPA), является использование оптимистической блокировки, поскольку она имеет тенденцию уменьшать количество конфликтов на уровне базы данных, позволяя продолжить чтение, пока происходят записи. Чтобы включить оптимистическую блокировку, нужно добавить аннотацию @Version к конкретному полю версии в вашем классе.

@Entity
public class Account {

    @Id
    private long id;

    @Version
    private long version;

    @Basic
    private BigDecimal balance;
}

Тогда реализация JPA будет управлять версией вашего объекта для вас. Рекомендуется оставить это поле закрытым и не указывать для него методы получения или установки, так как вы хотите, чтобы реализация JPA несла единоличную ответственность за это поле. В таком случае основное внимание будет уделено тому, какие действия предпринять при возникновении исключения OptimisticLockException (что происходит, если кто-то еще обновил одну из учетных записей, прежде чем вам удалось сохранить изменения.

К сожалению, нет единого решения этой проблемы, самый простой способ - перезагрузить две учетные записи и повторить транзакцию, что будет работать нормально, если у вас не слишком много транзакций, обращающихся к одной и той же учетной записи одновременно. В этом случае вы можете столкнуться с проблемами, когда некоторые запросы тратят большую часть своего времени на повторную попытку транзакции, однако лучше начать с простого решения, а затем изменить реализацию, как того требует ваше приложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...