【问题标题】:prevent period intersection in concurrent insert防止并发插入中的周期交叉
【发布时间】:2012-05-23 10:44:26
【问题描述】:

我有一个包含字段的表:name|...|start_date|end_date

我现在的代码是:

select .... 'check for period intersection
insert .... 'if check succesfull insert new row

此代码在一个事务中。 当两个用户尝试同时插入具有相同字段(和句点相交)的新记录时,插入了两条记录。 但我想避免插入。第一个用户必须插入,其他用户必须发生冲突。 我该怎么做?

附:我使用 IBM DB2

【问题讨论】:

    标签: java sql db2


    【解决方案1】:

    插入从选择中获取数据的查询。在选择中选择的值将需要插入的数据。 where 子句可以检查条件,如果检查失败,则应返回 null。因此,如果我想输入 id 5 不在表中而不是

      Insert into test1(val) select "test" from (select case when id = 5 then null else 5 end '1' from sysP where id =5) aa
    

    此查询将在表 test1 中插入 test is id =5 is not there in sysP table

    【讨论】:

    • 我想与 NOT EXISTS 一起使用
    • 不存在任何具体使用原因。
    • 插入 ... 选择 ... 不存在的地方(选择 ...)。我觉得适合我。
    • 如果不存在,将根据内部查询检查外部表的每一行。尝试在外部表中使用 sysibm.sysdummy1 和检查查询内部部分。我没有可用的 DB2 来测试这个。
    • 试试这个。假设 5 在表中,这不会返回任何东西。对于不在表中的 id 会给你 test select "test" from (select 1 id from sysibm.sysdummy1) s1 where not exists (select * from sysP s2 where s2.id = 5) go
    【解决方案2】:

    您可以使用英国或选择更新:

    select .... 'check for period intersection FOR UPDATE WITH RS USE AND KEEP UPDATE LOCKS
    

    更新: 尝试在选择之前锁定整个表:

    LOCK TABLE TABLE_NAME IN EXCLUSIVE MODE
    

    这样,第二个事务在选择之前等待前一个事务提交。 EXCLUSIVE MODE 也会锁定 select 语句,而不仅仅是更新和插入。

    更新 2: 如果“检查期间交叉点”仅使用与您插入的表相同的表中的列,则不要选择向表中添加约束检查。见http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=%2Fcom.ibm.db2.udb.admin.doc%2Fdoc%2Ft0004984.htm

    【讨论】:

    • 我不能使用唯一键,因为我检查交叉点,日期可以不同。
    • 假设我的桌子是空的。两个用户尝试同时插入记录(01.01.2012-31.01.2012 和 15.01.2012-31.01.2012)。如果我使用 FOR UPDATE 会发生什么?
    • @nkislitsin 我认为您需要锁定表。在这种情况下无需选择更新。
    • 你知道其他不加锁的变种吗?
    • @nkislitsin 我更新了答案。我的想法不多了:)
    【解决方案3】:

    听起来像MERGE 正是你想要的,当结合一些错误提示时。我假设您在 Linux/Unix/Windows 上使用 DB2,但 MERGE 自 v9.1 以来也一直在大型机 DB2 上。

    MERGE INTO YOUR_TABLE YT
    USING (
            VALUES ('val1', 'val2', 'val3')
        ) MG(v1, v2, v3)
     ON (TY.v1 = MG.v1)
    WHEN MATCHED 
        SIGNAL SQLSTATE '70001'
        SET MESSAGE_TEXT = 'Record already exists!'
    WHEN NOT MATCHED THEN
       INSERT(v1, v2, v3)
       VALUES(MG.v1, MG.v2, MG.v3
    ELSE IGNORE;
    

    USING 子句可以与提供的值一起使用(就像我在这里一样),或者它可以是一个子选择。我在上面链接的信息中心的合并页面上还有其他示例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 2017-04-26
      • 1970-01-01
      • 2021-09-25
      • 2017-03-03
      • 1970-01-01
      相关资源
      最近更新 更多