【发布时间】:2011-06-28 22:00:41
【问题描述】:
可能是一个微不足道的问题,但我想得到最好的解决方案。
问题:
我有两个或多个工人将键插入一个或多个表。当两个或更多工作人员尝试同时将相同的键插入其中一个键表时,就会出现问题。 典型问题。
- 如果存在键 (SELECT),则工作程序 A 读取表。没有钥匙。
- 如果存在键 (SELECT),则 Worker B 读取表。没有钥匙。
- 工人 A 插入密钥。
- 工人 B 插入密钥。
- 工人 A 提交。
- 工人 B 提交。违反唯一约束时抛出异常
键表是简单的对。第一列是自增整数,第二列是 varchar 键。
这种并发问题的最佳解决方案是什么?我相信这是一个普遍的问题。肯定的一种方法是处理抛出的异常,但不知何故,我认为这不是解决这个问题的最佳方法。
我使用的数据库是 Firebird 2.5
编辑:
一些额外的信息让事情变得清晰。
- 客户端同步不是一个好方法,因为插入来自不同的进程(工作者)。有朝一日,我可以让工作人员跨不同的机器,所以即使是互斥锁也是不行的。
- 此类表的主键和第一列是自增字段。那里没问题。 varchar 字段是问题所在,因为它是客户端插入的内容。
典型的此类表是用户表。例如:
1 2056 2 1044 3 1896 4 5966 ...每个工作人员检查用户“xxxx”是否存在,如果不存在则插入它。
编辑 2:
如果有人会走同样的路线,仅供参考。 IB/FB 返回一对错误代码(我使用的是 InterBase Express 组件)。检查重复值违规如下所示:
except
on E: EIBInterBaseError do
begin
if (E.SQLCode = -803) and (E.IBErrorCode = 335544349) then
begin
FKeysConnection.IBT.Rollback;
EnteredKeys := False;
end;
end;
end;
【问题讨论】:
-
阅读答案我刚刚有了一个想法。我可以有另一个工作人员,其唯一目的是插入关键数据。其他工作人员将通过 IPC 或 TCP 将数据发送给它。似乎是一个很好的解决方案,也适用于多台计算机。我还是想看看你们想出了什么。
-
所以用户试图插入一个键的重复值,该键被限制为唯一。他们会得到一个错误,这就是它应该的样子。有什么问题?
-
这是自动化工人,他们背后没有用户。数据来自工作人员操作的大型“记录”表。他们会做一些报告。如果发生异常,尝试重复选择/插入也许是正确的做法。我只是想就此事获得所有可能的意见解决方案。
标签: sql delphi concurrency firebird auto-increment