我使用Oracle 11g (它可能会影响解决方案)。我有像下面这样的版本表。我希望使原子操作包括从这个表中选择、插入到另一个表(取决于前一个表的状态)和更新前一个表的状态。
我想要简单的解决方案(简单的问题简单的解决方案?),原子和我想要避免死锁。我选择乐观锁定策略。
所以,我有这样的桌子
CREATE TABLE table (
id int,
version int,
state varchar(20)
);在伪码中,我有这样的东西:
Line 1: SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
Line 2: START TRANSACTION;
Line 3: SELECT state as S, version as V from table where id = X;
Line 4: if (S == 'TODO') then
Line 5: INSERT INTO other_table ...
Line 6: UPDATE table SET state = 'DONE', version = version + 1 WHERE id = X and version = V
Line 7: COMMIT;据我所知,另一个线程可以在第6行和第7行之间执行相同的代码块。然后(考虑隔离级别= read提交),我有两个插入到other_table,我不想这样做。
如何使这个代码块真正具有原子性?
我希望避免锁定行和序列化隔离级别(死锁)。
发布于 2015-10-21 10:14:17
不需要处理隔离级别,您可以首先执行UPDATE,如果更新成功,则执行INSERT。更新将锁定受影响的行(这里的oracle文档),因此另一个会话将被阻塞,直到第一个会话关闭其事务。
PL/SQL示例:
BEGIN
UPDATE t
SET state = 'DONE', version = version + 1
WHERE id = x
AND state = 'TODO';
IF( SQL%FOUND ) THEN
dbms_output.put_line( 'INSERT HERE' );
END IF;
END;
/https://stackoverflow.com/questions/33254755
复制相似问题