Если я хорошо понимаю вашу потребность, вы спрашиваете что-то деликатное, в некоторых контекстах. Позвольте мне попробовать пример , чтобы проверить, правильно ли я понимаю :
- Поток T1 читает pojo P в кеш, получает версию P1.
- Поток T2 читает pojo P в кеш, получает версию P1.
- Поток T2 начинает транзакцию, читает то же pojo, изменяет значение, которое создает версию P2.
- Поток T1 читает pojo P в кеш, все еще получает версию P1. Для этого требуется, чтобы для пункта 3 T2 получил копию P2 версии P1, а не тот же объект.
- Поток T2 сохраняет P, ничего не меняется ни для T1, ни для T2, у них разные версии.
- Поток T2 закрывает транзакцию:
а. в случае отката T2 будет использовать P1, как и T1.
б. если зафиксировать, T2 продолжит использовать P2. Но теперь T1 также должен использовать P2.
Вы видите, что это сложная проблема, не стоит ее недооценивать.
Есть много вопросов, которые нужно решить, уже на теоретическом уровне (и у вас будет больше, когда вы будете писать ...).
Ваша архитектура должна быть действительно ясной, если вы хотите использовать ее успешно.
Если нет, вы рискуете своим психическим здоровьем ;-)
Во-первых, Вам нужно убедиться, что вы действительно хотите что-то подобное!
Если ты действительно этого хочешь ..
Я предлагаю использовать технический код (AOP, ThreadLocal), чтобы скрыть эту сложную сложность от вашего функционального кода .
Вероятно, что ваш коммит / откат уже сделан через AOP, поэтому с этим проблем не должно быть.
Чтобы скрыть получение экземпляров P (иногда экземпляр в сохраненном кэше, иногда копию): используйте класс с именем Store для хранения значений в кэше, используйте переменную ThreadLocal типа Store. Я бы использовал переменную ThreadLocal для вашего текущего потока:
- Экземпляр Store может быть изменен только в вашем транзакционном коде AOP, но не в вашем функциональном коде
- Ваш функциональный код использует текущий экземпляр ThreadLocal для манипулирования объектами (сохранение и т. Д.) *
- когда вне транзакции , экземпляр ThreadLocal является кэшированным, назовем его CACHE.
- ввод транзакции устанавливает другой экземпляр ThreadLocal для текущего потока; этот класс является подклассом Store, который будет возвращать копии объектов кэшей, когда вы их запрашиваете; класс также запомнит, если некоторые из них сохранены (поэтому вам нужно сохранить их с помощью этого специального API или уведомить об этом в своем обычном API сохранения)
- откат транзакция отбрасывает экземпляр ThreadLocal, переустанавливая экземпляр CACHED для текущего потока
- принятие транзакция будет принимать все запомненные операции базы данных в экземпляре ThreadLocal, применять это для изменения экземпляра CACHED и переустанавливать экземпляр CACHED для текущего потока