【问题标题】:How to concurrently update a cached Java object如何同时更新缓存的 Java 对象
【发布时间】:2014-12-19 17:16:09
【问题描述】:

我正在尝试更新我的应用程序中的值,我们将其称为 Foo 对象。 Foo 作为 java 对象是不可变的,但可以通过 Hibernate 实体在数据库中更新。我通过调用加载缓存覆盖(Guava Cache 作为实现)来访问 Foo 对象,该覆盖在不存在时从数据库加载值。此外,虽然并发写入是可能的,但对 Foo 对象的写入会很少,但读取会很多。

更新 Foo 对象的最佳方法是什么?更新时锁定缓存?其他一些结构设计?

请注意,在广阔的互联网上肯定有关于这个主题的信息,但我阅读了很多内容试图弄清楚这一点,以至于我自己都感到困惑。我目前倾向于在缓存实现类的更新方法上使用 ReentrantLock,但似乎应该有更好的方法。

【问题讨论】:

  • 应用程序的各个部分是否需要知道“不可变”对象发生了变化?
  • @ThorbjørnRavnAndersen,不,我不这么认为,除非另一个“作者”需要知道它,这样我在更新对象时就不会出现竞争条件。
  • 通常的解决方案是在对象更新时触发事件,请参阅 Swing 以获取执行此操作的大型代码库的示例。您可以使用锁和同步来避免重叠更新。

标签: java caching concurrency immutability


【解决方案1】:

我不完全确定你的问题是否正确。但是问题似乎与我在这里回答的问题相同/相似:Guava Cache, how to block access while doing removal

如果没有,请添加更多详细信息。

【讨论】:

  • 您能否详细说明如何“触摸”数据以启动事务(链接中的解决方案#1),但仍保持数据层的抽象?我想我不明白你是如何让从业务层到数据层的两次往返都发生在一个事务下的。
  • 这确实似乎是我的设计问题,但锁定应该解决和竞争问题...我将尝试您的第三个解决方案,但有一个仅用于更新的特殊通道,如任何读取从 DB 将在 Hibernate 从更新中释放自动锁定之前或之后发生,我可以接受。此外,我正在使用来自 Guava 的 Striped 进行锁定条带化,尽管我确实喜欢你的快速而肮脏的解决方案。
猜你喜欢
  • 1970-01-01
  • 2011-11-05
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 2015-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多