我们有一个聚合某些数据的过程,并将结果插入到我们用于高效查询的另一个表中。我们面临的问题是我们现在有几个聚合器大致同时运行。
我们使用原始记录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)
答案 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可能是适当的序列化机制。