Есть ли способ реализовать решение без блокировки, чтобы обеспечить целостность данных в нескольких экземплярах

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

Например, я получил запрос для экземпляра A, говорящий, что значение должно быть увеличено на 5, и в то же время другой запрос для экземпляра B увеличил значение на 1, и так далее...

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

    protected Lock getLock(String seqName) {
        Lock oldLock, dbSequenceLock = dbSequenceLocks.get(seqName)
        if (dbSequenceLock == null) {
            dbSequenceLock = new ReentrantLock()
            oldLock = dbSequenceLocks.putIfAbsent(seqName, dbSequenceLock)
            if (oldLock != null) return oldLock
        }
        return dbSequenceLock
    }

     protected String update(String seqName, int value) {
        try{
            Lock dbSequenceLock = getDbSequenceLock(seqName)
            dbSequenceLock.lock()
            Type record = selectForUpdate(seqName);//This selects the 
            entity for update
            record.set("val", record.get("val") + val);//increment or decrement the value...
            record.update();
        } finally {
            dbSequenceLock.unlock()
        }

Я не уверен, что это лучший способ сделать это, и если я могу как-то избавиться от блокировки, какие-либо предложения?

1 ответ

Предполагая, что вы поддерживаете ACIDity базы данных, эти транзакции будут изолированы друг от друга. Так что, если у вас нет очень медленных запросов на обновления, это не будет иметь значения. Запрос, который выполняется позже, обновит запись и будет сохранен.

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

Другие вопросы по тегам