Под продуктом распределенного кэша я имею в виду что-то вроде Coherence или Hazelcast. Я буду использовать Hazelcast в качестве примера.
Предположим, у меня есть объект, который сохраняет состояние на нескольких картах:
class DataState {
Map<ID, Dog> dogs = Hazelcast.getMap("dog");
Map<ID, Owner> owners = Hazelcast.getMap("owner");
public void associate(Dog dog, Owner owner) {
/* ... put in maps and set up references */
}
}
Обратите внимание, что функция associate () должна быть транзакционной, поскольку она изменяет несколько карт. Так как собаки и владельцы так или иначе связаны, возможно, что данные находятся в несогласованном состоянии до завершения метода. Теперь, если другой класс читает из распределенной памяти, он не имеет представления о том, что происходит транзакция, и может видеть данные непоследовательно.
class DataStateClient {
Map<ID, Dog> dogs = Hazelcast.getMap("dog");
Map<ID, Owner> owners = Hazelcast.getMap("owner");
public void doSomething() {
// oops, owner2 is associated with dog1 but
// dog1 is not yet in the map!
}
}
Теперь Hazelcast распространил блокировки, чтобы решить что-то вроде этого, но каковы последствия для производительности? Предположим, что doSomething () стоит дорого (например, копирование обеих карт локально), и в этом случае может быть недостаточно заблокировать несколько клиентов.
Существует ли стандартное решение этой проблемы распределенной синхронизации?