21

我有一个缓存启动 SOAP 调用的微小/简单结果的系统

我需要实例能够在启动时重新加载它们的缓存(以防 SOAP 服务失效),并且还需要处理多个实例使用此缓存文件的可能性

我选择使用java.util.prefs,但 Java 的内置自动同步线程间歇性失败(1% 的时间使用默认的 JVM 30 秒后备存储同步)转储以下异常:

Jan 8, 2010 12:30:07 PM java.util.prefs.FileSystemPreferences syncWorld
WARNING: Couldn't flush user prefs: java.util.prefs.BackingStoreException: Couldn't get file lock.

我怀疑这个错误,但这已在 1.5(tiger-b40) 中修复,我们在这个盒子上的 java 5 是“1.5.0_16-b02”。

我现在怀疑这可能是因为我们有多个 JVM 共享这个后备存储,尽管这似乎不会在我们的其他机器上发生。

谁能证实这一点?有什么风险,如果有的话?

如果我的方法有缺陷,我应该使用什么作为替代方法?

4

3 回答 3

11

“我现在怀疑这可能是因为我们有多个 JVM 共享这个后备存储”

绝对可能是这种情况!如果两个 JVM 试图同时锁定文件,那么这就是您将看到的。

确切的细节取决于锁的类型、操作系统和文件系统。

您可能想尝试将导致此问题的操作包装在 try/catch 块中,然后在失败时重试该操作。

于 2010-01-09T21:55:00.157 回答
1

我在码头遇到了同样的问题。我发现以下解决了这个问题。

将一个添加.systemPrefs到您的 JRE 目录,并为运行正在抱怨的进程的用户提供访问权限。

完成后,转到 Jetty 目录并打开start.ini文件

-Djava.util.prefs.userRoot={user's home directory}

-Djava.util.prefs.systemRoot={user's home directory}

添加完这些行后,我重新启动了码头,发现错误消失了。

于 2014-09-18T22:48:37.527 回答
0

而不是使用首选项,只需使用任何可序列化的 Map 并创建一个非常简单的缓存类,将其序列化和反序列化为随机生成的临时文件名(第一次初始化时生成的文件名)。由于它只是一个缓存,因此您可以捕获任何异常并在发生异常时将缓存重置为其初始状态,因此它将从原始数据源(在您的情况下为 SOAP 服务)重新获取。因此,如果您不想担心 serialVersionUID 或任何兼容性问题,则无需担心。

于 2011-04-12T10:24:07.310 回答