我正在研究IBM DB,但我认为这些概念几乎相同。
我想获取一行,返回这些数据(或者将它们保存到变量中)并更新该特定行的某些字段。可能有许多实例尝试同时执行该查询,因此我们需要获取原子操作。
每行都有一个名为pending的字段,init为FALSE。当一个实例获取此行时,将其设置为TRUE(这是我想要执行的更新)。我需要它的原因也是原子的,是我的查询获取表的第一行,其中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();
不要担心语法,它们是宏,只要它们自己执行就可以工作。我猜这个问题出在第二个查询上,但为什么呢?
我想这与我正在使用的数据库没有关系。
如果我评论第二个,代码可以正常工作。如果我单独执行第二个,它也可以。
答案 0 :(得分:1)
选项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应该可以很好地工作,除非你选择&和更新