管理DB2中数据插入的并发性

时间:2014-11-20 09:01:12

标签: concurrency db2

我目前正在进行研究,并想知道目前有哪些方法或算法来管理多用户数据插入两个关系表(通过主键和外键相关)。

在主键表中,
- 主键可以是自动递增ID或非自动递增ID。

在外键表中 - 每次将新记录插入主键表时,必须将2条记录插入外键并指向新记录的主键

目前我正在这样做。
1.我有2个表(不带增量的主键表)(外键表)
我有另一个表(计数器)存储最大的主键值
3.每次用户插入新记录时,它将读取最大的主键值+ 1
4.然后它将开始事务并使用commit语句将三个记录分别插入主键表和外键表中

我关注的是市场上有哪些替代品?

3 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题,您会担心确定需要在子记录中使用的刚刚插入的父记录标识值。有几种方法可以实现这一点(我在这里假设我们正在谈论DB2 for Linux,Unix和Windows,因为你没有指出你的DB2版本和平台)。

如果使用IDENTITY属性定义父PK列,则可以使用内置函数IDENTITY_VAL_LOCAL()引用刚刚生成的标识值。

如果使用SEQUENCE生成键值,则在插入父表时使用引用NEW VALUE FOR myseq,对子表使用PREVIOUS VALUE FOR myseq

最后,您可以使用名为"数据更改表引用"的功能,它允许您获取DML语句的结果:

SELECT yourpk_column FROM FINAL TABLE ( INSERT INTO yourparent_tab... )

您甚至可以使用单个语句插入父表和子表(在此示例中,person.person_id定义为IDENTITY):

WITH parent (person_id) AS (  
  SELECT person_id FROM FINAL TABLE (
    INSERT INTO person (first_name, last_name) VALUES ('John', 'Doe')   
  )
)
SELECT * FROM NEW TABLE (
  INSERT INTO person_phone (person_id, type, number)
     SELECT person_id, 'Office', '555-555-1234' FROM parent
    UNION ALL
     SELECT person_id, 'Home', '555-555-6789' FROM parent) 

答案 1 :(得分:1)

正如其他人所说,您可以使用DBMS提供的IDENTITY。

但是,如果您希望使用自己的计数器,但也计划并发进程,那么您可以采取两种方法:锁定要更新的计数器,或仔细检查没有其他进程更新它并重新试试它是否确实如此。

要锁定,您可以选择...进行UPDATE(在将并发模式设置为UPDATE时选择)。这将允许您从游标中读取值,更新当前行,并在读取和更新之间锁定记录。您将需要在更新后立即释放锁定;因此,如果INSERT由于某种原因失败,您将得到一些从未使用过的序列号(这通常不是问题)。

生成GUID类型值的另一种方式(虽然TIMESTAMP可能已经足够了)并在递增序列号时更新它。获取时,您可以仔细检查GUID是否未更改。如果有,则表示另一个进程进行了更新。所以,你必须重试。

希望这表明为什么将更多努力工作留给DBMS可能更容易。 OTOH,它并不像看起来那么复杂,使用你自己的计数器也有实际的优势。

答案 2 :(得分:0)

使用"计数器"用于跟踪您描述的一个或多个ID的表是一种设计模式,通常会导致计数器表中的行争用非常频繁,并且即使只有适度的新密钥生成率,也会出现大量的并发问题。

DBMSs很久以前就用IDENTITY列(又名"自动增量")和/或SEQUENCES解决了这个问题。

即使使用标识或序列,当您在存储这些值的列上有索引时,也可能在非常非常高插入率时遇到并发问题。身份和序列通常是单调的,因此您可以进入最高"最高"存储这些值的列的索引页可能会导致并发问题。