【发布时间】:2010-11-15 12:42:10
【问题描述】:
嘿伙计们,这是我无法弄清楚的一个。我们在数据库中有一个表,PHP 在其中插入记录。我创建了一个触发器来计算要插入的值。计算的值应该是唯一的。但是,有时我在表中的几行有完全相同的数字。数字是年月日的组合和当天的订单号。我认为插入的单个操作是原子的,并且在事务进行时表被锁定。我需要计算的值是唯一的...服务器是 5.0.88 版本。服务器是双核处理器的Linux CentOS 5。
这里是触发器:
CREATE TRIGGER bi_order_data BEFORE INSERT ON order_data
FOR EACH ROW BEGIN
SET NEW.auth_code = get_auth_code();
END;
相应的例程如下所示:
CREATE FUNCTION `get_auth_code`() RETURNS bigint(20)
BEGIN
DECLARE my_auth_code, acode BIGINT;
SELECT MAX(d.auth_code) INTO my_auth_code
FROM orders_data d
JOIN orders o ON (o.order_id = d.order_id)
WHERE DATE(NOW()) = DATE(o.date);
IF my_auth_code IS NULL THEN
SET acode = ((DATE_FORMAT(NOW(), "%y%m%d")) + 100000) * 10000 + 1;
ELSE
SET acode = my_auth_code + 1;
END IF;
RETURN acode;
END
【问题讨论】:
-
你为什么不把时间包括到毫秒。或者取一个序列/自动递增的数字并添加它。
-
我秒自增数,如果你不使用某种内部的计数器方法,你会有竞争条件的风险
-
嗯...每一行都有一个唯一的自动增量编号。但是,计数的数字用于其他目的。订单被输入到表格中,然后精细状态机将其拾取并发送给遗留系统处理。然后,表中的顺序在通过精细状态机时会更改状态。旧系统支持所描述格式的 10 位数字。因此,添加自动增量将在总共 9999 个订单后停止系统...
-
ZaQ 是对的。只要您不依赖系统范围的自动增量/序列(对不起,我习惯了 Oracle 术语),您将始终在此过程中遇到竞争问题。我对 MySQL 不是很熟悉,但应该可以从某种系统范围的序列提供程序中获取下一个数字,而不是在代码中添加一个。
-
单个语句是原子的,但它指的是实际查询。存储过程不是原子操作 - 它是一系列单独的原子操作。你需要一个事务和一些锁来保证你得到一个唯一的 MAX(d.auth_code)
标签: mysql sql stored-procedures triggers