我有一个表,它只通过传入这个过程来创建。
这有点像CREATE触发SEQUENCE发电机。
(我们不能停止数据库创建触发器)和>。我已经要求过好几次了。所以必须手工创建)
DO TRANSACTION ON ERROR UNDO, RETRY:
FIND LAST mensagem NO-LOCK NO-ERROR.
IF AVAIL im THEN
INextID = mensagem.mensagem_id + 1.
ELSE
INextID = 01.
IF CAN-FIND(mensagem WHERE mensagem.mensagem_id = iNextID) THEN
UNDO, RETRY.
CREATE mensagem.
/* mensagem_id is a unique, primary index */
ASSIGN
mensagem.mensagem_id = INextID
mensagem.field1 = value1
mensagem.field2 = value2
.
END.
这个过程在一分钟内被访问几次,有时可能发生在同时调用它的两个程序上,比如试图创建两个具有相同值的对象。
我的问题是:如何防止mensagem already exists with mensagem_id 'INextID'
错误?
(考虑INextID作为下一个数字)。
当这个错误发生时,它没有循环通过TRANSACTION块而不是在桌子上创造信息。
(我已经尝试用no - error参数调用。p,但也没有成功)
在您的示例代码中,您(可能)在ASSIGN语句中偶尔发生冲突,因为FIND, can -FIND和CREATE之间可以传递少量时间;分配。在此期间,另一个进程可以进入并使用您希望使用的值。所以你需要在ASSIGN中添加NO-ERROR,然后通过先检测然后重试来处理被抑制的错误。
像这样:
ASSIGN
mensagem.mensagem_id = INextID
mensagem.field1 = value1
mensagem.field2 = value2
NO-ERROR.
if error-status:num-messages > 0 then
undo, retry.
然而,使用序列是防止序列号冲突的最好方法,这将是一个更好的方法。
可以在线添加序列,不需要停止数据库。如果你是OE12.2或更高版本,你也可以在线添加触发器。