Click here to view and discuss this page in DocCommentXchange. In the future, you will be sent there automatically.

SQL Anywhere 11.0.1 (中文) » SQL Remote » SQL Remote 复制设计 » SQL Remote 复制设计和设置 » 更新冲突 » 使用触发器的自定义冲突解决方法

 

解决库存冲突

假设有一个体育用品制造商的仓库系统。有一个产品信息表,其中的 Quantity 列保存每种产品的库存数量。对此列的更新通常是减少库存量,如果是有新货物入库,则增加库存量。

某远程数据库的销售代表输入一个订单,将小号无袖紧身 T 恤衫的库存减少 5 件(从 28 减到 23),并在她的数据库中输入此信息。同时,在将此更新复制到统一数据库之前,另一个销售代表收到了 40 件退回的 T 恤衫。该销售代表在他的远程数据库中输入此退货信息,并将更改复制到仓库的统一数据库,从而使 Quantity 列的数字增加了 40(变为 68)。

第一个更新在 Quantity 列加上 40。

仓库的输入数据被添加到数据库中:Quantity 列现在显示库存中有 68 件小号无袖紧身 T 恤衫。当来自第一个销售代表的更新到达时,便会导致一个冲突—SQL Anywhere 检测到更新是从 28 减到 23,但是该列的当前值是 68。

缺省情况下,最新的更新会成功,库存量将被设置为不正确的值 23。

不正确的冲突解决:第二个更新错误地覆盖第一个更新。

在本示例中,应该这样解决冲突:将更改变动累加到库存列以生成结果,从而将最终值 63 放置到数据库中。

正确的冲突解决:第二个更新修改第一个更新。
实现解决方案

适用于此情况的 RESOLVE UPDATE 触发器将添加来自两个更新的增量。例如:

CREATE TRIGGER resolve_quantity
 RESOLVE UPDATE OF Quantity
 ON "DBA".Products
 REFERENCING OLD AS old_name
  NEW AS new_name
  REMOTE AS remote_name
 FOR EACH ROW
 BEGIN
   SET new_name.Quantity = new_name.Quantity
                        + old_name.Quantity
                        - remote_name.Quantity
 END;

在执行 UPDATE 语句之前,此触发器将统一数据库中的旧值 (68) 与最初的 UPDATE 语句执行时远程数据库中的旧值 (28) 之间的差值与要发送的新值相加。这样,new_name.Quantity 变为 63 (= 23 + 68 - 28),此值被输入到 Quantity 列中。

远程数据库的一致性是通过以下方式保持的:

  1. 原始远程 UPDATE 语句将值从 28 更改为 23。

  2. 仓库的输入被复制到远程数据库,但是由于旧值不是预期的值,所以复制将失败。

  3. RESOLVE UPDATE 触发器进行的更改被复制到远程数据库。