如何在避免与oracle的唯一约束的同时插入

时间:2013-02-18 04:54:48

标签: oracle locking duplicates

我们有一个聚合某些数据的过程,并将结果插入到我们用于高效查询的另一个表中。我们面临的问题是我们现在有几个聚合器大致同时运行。

我们使用原始记录id作为此新表中的主键 - 一个唯一约束。但是,如果两个聚合进程同时运行,则其中一个聚合进程会因唯一约束违规而出错。

有没有办法指定某种锁定机制,使第二个编写器等到第一个完成后?或者,有没有办法告诉oracle忽略该特定行并继续其余行?

不幸的是,将聚合减少到单个进程是不切实际的,因为以下过程依赖于可用数据的最新版本,并且这些过程确实需要向外扩展。

编辑:

以下是我的[编辑]查询:

INSERT INTO
agg_table
SELECT
h.id, h.col, h.col2
FROM history h
JOIN call c
ON  c.callid = h.callid
WHERE
h.id > (SELECT coalesce(max(id),0) FROM agg_table)

3 个答案:

答案 0 :(得分:2)

可以使用错误记录子句运行INSERT语句。 Oracle文档中的示例如下:

INSERT INTO dw_empl
  SELECT employee_id, first_name, last_name, hire_date, salary, department_id 
  FROM employees
  WHERE hire_date > sysdate - 7
  LOG ERRORS INTO err_empl ('daily_load') REJECT LIMIT 25

或者,您可以尝试使用[MERGE][2]语句。您将使用详细信息表中的选择合并到摘要表中。如果找不到匹配项,则为INSERT,如果找到,则为UPDATE。我相信这个解决方案会处理你的并发问题,但你需要测试它。

答案 1 :(得分:0)

查看FOR UPDATE条款。如果在更新/插入语句之前在事务中正确编写带有FOR UPDATE子句的SELECT语句,则可以“锁定”所需的记录

答案 2 :(得分:0)

序列化插入可能是最好的方法,因为没有方法可以解决多个插入无法看到每个插件的问题。

DBMS_Lock可能是适当的序列化机制。