4

在我的 Java webapp 中,每个实例都在启动时检查数据库是否通过 JDBC 连接是最新的。如果数据库不是最新的,它会通过执行 SQL 脚本来执行更新例程。

我无法控制实例何时启动。因此,我需要确保只有一个实例同时执行数据库更新。理想情况下,我需要锁定整个数据库,但根据

http://www.postgresql.org/docs/8.4/static/explicit-locking.html

http://wiki.postgresql.org/wiki/Lock_database

PostgreSQL 不支持它(我仍在使用 8.4 版)。

我还有什么其他选择?

4

2 回答 2

4

如果您控制所有实例的代码,那么您可以在数据库中创建一个表,每个实例从该表开始,在该表中查找带有时间戳的记录。让我们称它为您的“锁定”记录。

如果进程发现锁记录不存在,则插入记录并处理您需要的数据。

如果一个进程发现锁记录确实存在,那么您可以假设另一个进程已经创建了它并且什么也不做,忙等待,或者其他什么。

通过这种设计,您可以有效地在数据库中创建一个“锁”来同步您的流程。您对其进行编码,因此所有进程都知道它们必须遵守锁定记录的逻辑。

一旦第一个拥有锁的进程完成处理,它应该清除锁记录,以便下一次重新启动正常运行。您还需要考虑由于服务器错误或执行错误导致锁没有被清除的情况。通常,如果锁超过n分钟,您可以认为它是“陈旧的”,因此删除它,然后再次创建它(或只是更新它)。

在处理“锁定”记录时,请务必在数据库连接上使用Serializable隔离级别,以保证原子性。

Java 代码的服务层可以在调用数据访问层之前执行锁定策略。是否使用 Hibernate 无关紧要,因为它只是应用程序逻辑。

于 2012-09-06T13:46:49.763 回答
0

理想情况下,我需要锁定整个数据库。

只要您有效地序列化访问,您的锁适用于什么真的很重要吗?只需在任何表或行上获取排他锁即可。

于 2012-09-06T13:46:50.907 回答