如何控制并发以不同进程同时访问行

Posted

技术标签:

【中文标题】如何控制并发以不同进程同时访问行【英文标题】:How to Control Concurrency to access the Row by Different processes at same time 【发布时间】:2020-12-20 07:08:48 【问题描述】:

我的 Oracle DB 有一个名为 CONFIG 的表

 CONFIG:
    | Name     | Value  |
    | -------- | ------ |
    | Modifier | A      |

我的要求是编写一个访问名为“Modifier”的流的过程,将值加一并更新表并返回值。

但问题是当两个进程同时访问该行时,如何控制并发。 示例:

假设有两个事务 T1 和 T2。它们并行运行。 让我们最初说修饰符是 A

T1 运行并将修改器更新为 B T2 也同时运行并更新 Modifier,应该更新为 C 而不是 B。

【问题讨论】:

您可以使用锁并依赖关系完整性。 【参考方案1】:

您需要使用带有 FOR UPDATE 语法的显式游标来获取表上的锁。

create or replace function update_modifier return varchar2 as
  cursor get_config is
    select * 
    from config
    where name = 'modifier'
    for update of value;
  r_config config%rowtype;
begin
  open get_config;
  fetch get_config into r_config;

  -- I'm not going to guess at your logic for "incrementing" a string
  r_config.value := 'something';

  update config
  set value = r_config.value
  where current of get_config;

  commit;

  close get_config;

  return r_config.value;

end update_modifier;

注意事项

当我们打开游标时,FOR UPDATE 会在表上获取行级锁。锁定一直保持到我们发出提交(或回滚)为止。 调用此过程的任何其他会话将等待此会话释放锁定。如果您希望其他会话的调用返回,请使用 NOWAIT 选项。或者使用 WAIT 指定等待锁释放的秒数,然后再中止。 文档中对此进行了介绍。 Find out more

【讨论】:

以上是关于如何控制并发以不同进程同时访问行的主要内容,如果未能解决你的问题,请参考以下文章

Linux 如何查看进程和控制进程

为啥数据库系统要采用并发控制?

mysql基础之存储引擎

Oracle 锁

linux设备驱动中的并发控制

2016-06-27 并发编程