数据库:在事务中获取一个后执行更新查询

DB : perform an update query after a fetch one inside a transaction

我在 IBM 数据库上工作,但我认为概念几乎相同。

我想获取单行,return 这些数据(或者说将它们保存到变量中)并更新该特定行的某些字段。可能有多个实例同时尝试执行该查询,因此我们需要获取操作是原子的。

每一行都有一个字段叫pending,初始化为FALSE。当一个实例获取这一行时,它被设置为 TRUE(这是我想要做的更新)。我需要它也是原子的原因是我的查询获取 table 的第一行,其中 pending 为 FALSE。

在伪代码中我有这样的东西:

OPEN_DB(myDb, "DBNAME");  // opening the DB
BEGIN_TRANSACTION(myDb);  // beginning transaction on my db
EXECUTE_QUERY(myDb,"SELECT * FROM tbname WHERE pending == 0 ORDER BY colid LIMIT 1");
... assign a cursor to my results
while (valid_data) {
    // assign column fields to variable

    // and here i want to do the update for this column
    // I guess the problem is here
     EXECUTE_QUERY(myDb,"UPDATE tbname SET pending = 1 WHERE colid=@colid")

}
COMMIT();

不用担心语法,它们是宏,一旦单独执行它们就可以工作。我猜问题出在第二个查询上,但为什么呢?

我想这与我使用的数据库无关。

如果我评论第二个,代码就可以工作。如果我单独执行第二个,它也能正常工作。

选项 1 - 为 curor 做一个select for update,这将是悲观锁定

选项 2 - 执行乐观锁并处理异常。锁需要像上次更新时间或版本这样的列,如下所示:

OPEN CURSOR

UPDATE table set col = :new_value
WHERE id = :id_from_cursor
last_updated = :last_updated_from_cursor;

CHECK if update row count == 1 COMMIT
IF not throw exception

虽然我认为选项 1 应该很好用,除非你在 select 和更新

之间有很大的时间间隔