我们已经为我们的 J2EE 应用程序创建了一个缓存层。在本例中,我们使用 Ehcache。这带来了一些挑战。
让我们举个例子。
OrderItem orderitem = cache.getOrderItemByID("id");
OrderItem old_orderitem = cache.getOrderItemID("id");
orderitem.setStatus(1);
old_orderitem.setStatus(2);
如果我们不小心,对这些对象中的任何一个所做的任何更改都会影响另一个(它们引用相同的对象)。将 orderitem 保存回数据库将使其具有 status=2
我们如何最好地解决这个问题?
我们已经尝试为每个对象创建一个 .copyObject() 方法。它只是创建一个新对象并设置所有值。但这似乎不是一个好的解决方案。
这个例子只是为了说明。代码远比这复杂,但结果是一样的。
************************更新 15.07.2010 ********************* ******************************
在 EHCache 2 中,有一些选项可以打开 copyRead() 和 copyWrite()。这解决了我所有的问题:)
最佳答案
这是可变状态的问题。它不仅是缓存,任何时候你都可以对同一个对象有多个引用并且该对象是可变的。例如:
HashMap map = new HashMap();
map.put("one", new OrderItem());
OrderItem one = map.get("one");
OrderItem two = map.get("one");
one.setStatus(1);
two.setStatus(2);
会有完全相同的问题。当您拥有并发环境时,这会变得更加复杂。解决这个问题的一种方法是只使用不可变对象(immutable对象)。这样,如果您想要一个具有不同状态的对象,您将不得不创建一个新对象。它还使并发编程更容易。
您考虑复制对象是正确的。您的选择是:
- Cloning
- Deep copying via serialization
- 通过复制构造函数进行深度复制
每个都有自己的长处和短处,哪一个最有效取决于您的环境。
关于具有缓存层的 Java 对象引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2022190/