我有一个java应用程序从数据库表读取要处理的作业,我可能有多个这个应用程序的实例在不同的服务器上运行,因为每个作业是独立的.一旦找到作业进行处理,其状态将更新为"正在运行".我想要确保从每个实例检索要处理的作业是原子的,我如何使用JDBC实现这一点?
一种完全通用*但可能效率稍低的方法是使用服务器特定的标识符来"声明"作业,方法是首先将其状态更新为该标识符,然后根据该值检索作业.例如,如果您在同一网络上使用Windows服务器,那么它们的服务器名称将唯一标识它们.如果你的表看起来像
JobID JobName Status
----- ------- ---------
1 Job_A Completed
2 Job_B
3 Job_C
Run Code Online (Sandbox Code Playgroud)
如果无人认领的作业具有状态,NULL则在SERVER1上运行的应用程序可以通过执行setAutoCommit(true)后续操作来声明作业
UPDATE Jobs SET Status='SERVER1'
WHERE JobID IN (
SELECT TOP 1 JobID FROM Jobs
WHERE Status IS NULL
ORDER BY JobID)
Run Code Online (Sandbox Code Playgroud)
如果ExecuteUpdate返回0则没有待处理的作业.如果它返回1,那么你可以得到行
SELECT JobID, ... FROM Jobs WHERE Status='SERVER1'
Run Code Online (Sandbox Code Playgroud)
然后使用参数化查询将其状态更新为"正在运行"
UPDATE Jobs SET Status='Running' WHERE JobID=?
Run Code Online (Sandbox Code Playgroud)
在哪里提供从上一个SELECT中检索到的JobID.
*(即,不依赖于任何特定的SQL扩展,显式锁定或事务处理)
使用数据库服务器支持的任何机制锁定表。
例如,在 Postgres 中它将是:
LOCK yourtable;
Run Code Online (Sandbox Code Playgroud)
这是您在交易期间的表格。
其他数据库也会有类似的东西。