我有两个表,Order
和Slot
。每个插槽都有时间,但为简单起见,我们将其表示为整数。像这样的东西:
Order Slot
----- ----
order_id slot_id
earliest order_id
latest time_from
time_to
我正在尝试更新earliest
和latest
,以使earliest = MIN(slot.time_from)
和latest = MAX(time_to)
。 time_from < time_to
一直都是这种情况,但这在这里并不重要。
为此,我在UPDATE上创建了一个触发器,在Slot上创建了一个INSERT。触发器:
CREATE OR REPLACE FUNCTION keep_orders_updated() RETURNS trigger AS $trigger$
BEGIN
UPDATE "order"
SET earliest=d.earliest_min, latest=d.latest_max
FROM (SELECT MIN(time_from) as earliest_min, MAX(time_to) AS latest_max FROM "slot" WHERE order_id = NEW.order_id) AS d
WHERE order_id=NEW.order_id;
RETURN NULL;
END;
$trigger$ LANGUAGE plpgsql;
CREATE TRIGGER keep_orders_updated_trigger AFTER INSERT OR UPDATE ON "slot" FOR EACH ROW EXECUTE PROCEDURE keep_orders_updated();
[在大多数情况下,它会产生正确的结果,除了以下情况,我正在尝试解决。我们从以下数据开始:
Order:
order_id | earliest | latest
----------+------------------------
1 | 10 | 20
Slots:
slot_id | order_id | time_from | latest
----------+------------------------+------------------------
1 | 1 | 10 | 12
1 | 1 | 18 | 20
并且在两个并发事务中(在我的情况下,它们是使用来自Web服务器中连接池的不同连接运行的,基本上服务于大约同时到达的两个请求:]]
tx1: UPDATE "slot" SET time_from=15 AND time_to=17; tx2: UPDATE "slot" SET time_from=19 AND time_to=25;
我获得了正确更新(预期)的广告位,并且订单更新错误。仅最新更新:
Order: order_id | earliest | latest ----------+------------------------ 1 | 10 | 25
类似地,如果我将time_from设置为小于10的值,它将更新。
我想我理解为什么会这样。相关行上的每个插槽更新块均会阻止更新同时运行。触发器仅看到其事务更新的数据,而不看到其他事务更新的数据。结果,它为tx1计算MIN(10,15),为tx2计算MIN(10,19),并按照相关顺序将其最早设置为10。
我的理解正确吗?如何使这样的配置正常工作?
我有两个表,即Order和Slot。每个插槽都有时间,但为简单起见,我们将其表示为整数。像这样的东西:订单位----- ---- order_id slot_id ...
代替存储此派生信息,为什么不创建视图?