我正在使用Postgresql,我需要一种方法来锁定工作过程中的特定线路,这个过程是在线路上操作的。它本质上是一个动作表,应该只执行一次。每个过程都应该抓住不同的行。 . z& \' A- ?& ^9 K在这个操作过程中,工作过程会计算一些值并多次插入事务(计算和插入数据库会有所不同)。4 ^; A& C: a, R7 ]% ^& d" s
我不知道每个操作需要多长时间(它会有所不同),如果过程死亡/被杀或系统崩溃,我需要一种解锁银行的方法(这样其他过程就可以抓住银行并完成操作)% i- a. G- t0 E# j
)。4 a! B8 f+ ?! L: S7 @7 {
据我所知,Postgresql行锁只存在于一个事务中。当时我想加一些标志,指示行是否锁定在表中,但我很难弄清楚如何知道银行是否还在操作,或者是否正在挂断,因为工作过程死了(后者应该由其他工作过程处理)?(我在表中有一个完成标志,表示银行已经完成/正在处理)% i+ o* ~ k9 o/ d& M U, ?% R
, w" T' d: A2 I; G; |解决方案: 9 |; q; @) L7 C) n" {0 ` 使用标志的解决方案似乎可行,我认为唯一需要做的就是使锁失效。基本上,我构造锁的方式是,我将在获取锁时编写一个时间戳记,并使其成为时间戳,以便该过程在保持记录工作的同时,必须经常(即每30秒): |' z, n# a- J/ j8 J6 b3 p4 y
更新 一次锁。如果过程终止或其他方式无法完成,锁定将过期,如果超过时间的两倍,其他过程可以 将 其 解锁 。 - t; w2 Y& ?& f: ?% A+ A) Z! H对记录进行处理时,将锁定标记清除并标记为已处理(再次标记)。6 J' Z. J6 v3 z* W' s
你可能希望有两个字段:一个戳存储时间锁定标志,另一个指示哪个过程有锁(以防万一,你需要关心它)。我假设有一个按钮可以用来排序表中的记录,以使下一个操作的概念有意义。0 j& `# f6 A$ b/ [
您可以使用此查询获取下一个要处理的记录:" T) v. H" }, e2 f7 ]
-- find the next available process and "lock" it by updating it's flag UPDATE actions_tabe SET LockFlag = @timestamp, Process = @processname WHERE Id IN (SELECT Id FROM actions_table WHERE LockFlag IS null AND IsComplete = AND ScheduledTime < now() ORDER BY Scheduledtime ASC,Id ASC LIMIT 1); -- return the Id and Action of the record that was just marked above SELECT Id,Action FROM actions_table WHERE Process = @processname