2010-11-15 98 views
0

嘿,这里是我无法弄清楚的一个。我们在数据库中有一个表格,PHP插入记录。我创建了一个触发器来计算要插入的值。计算的值应该是唯一的。然而,我经常会发现表格中的几行有完全相同的数字。该数字是年,月和日的组合以及当天的订单数量。我认为插入的单一操作是原子的,并且在事务正在进行时表被锁定。我需要计算的值是唯一的...服务器版本是5.0.88。服务器是带有双核处理器的Linux CentOS 5。MySQL事务和触发器

这里是触发:

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 
+0

为什么不把时间缩短到ms。或者选择一个序列/自动增量编号并添加它。 – Jules 2010-11-15 12:54:21

+0

我第二个自动递增数字,如果你不使用某种内部方法的计数器,你将有竞争条件的风险 – ZaQ 2010-11-15 12:56:49

+0

那么......每一行都有一个独特的自动增量编号。但是,计数的数字用于其他目的。订单被输入到表格中,然后好的状态机将它拿起并发送给遗留系统处理。表格中的顺序随着其在精状态机中的进展而改变。旧系统支持所描述格式的10位数字。因此,添加自动增量会在系统完成9999次订单后暂停系统... – user390133 2010-11-15 14:33:29

回答

2

我认为 插入的单一操作是原子和表被锁定 而交易是在进展

表中的任何一个被锁定(使用MyISAM)或记录可能被锁定(使用InnoDB),而不是两者。

既然您提到“交易”,我认为InnoDB正在使用中。 InnoDB的优势之一是没有表锁,所以没有什么会阻止许多触发器的主体同时执行并产生相同的结果。