我们有一个表,其中包含引用系统处理的每个事务的计数器的记录。
以下是表格的表格定义:
CREATE TABLE `controlnumber` (
`StoreCode` varchar(10) NOT NULL,
`TerminalNumber` varchar(10) NOT NULL,
`TransactionType` varchar(25) NOT NULL,
`LastSeries` bigint(20) unsigned DEFAULT NULL,
`Prefix` varchar(10) NOT NULL,
PRIMARY KEY (`StoreCode`,`TerminalNumber`,`TransactionType`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
表格中的数据样本如下:
+------------+----------------------+------------+
| LastSeries | TransactionType | StoreCode |
+------------+----------------------+------------+
| 1 | Adjustments | HeadOffice |
| 111982 | Direct Transfer | HeadOffice |
| 975 | Location Transfer | HeadOffice |
| 8065 | Receiving | HeadOffice |
+------------+----------------------+------------+
创建使用此表的事务时,代码如下:
申请代码(vb6):
connection.BeginTrans
connection.execute("CALL saveReceiving(...)")
connection.execute("UPDATE controlnumber SET lastSeries = lastSeries + 1 WHERE TransactionType = 'Receiving' AND StoreCode = ...")
connection.CommitTrans
SQL代码:
CREATE PROCEDURE saveReceiving(...)
BEGIN
//The "receiving" table is an InnoDB table
INSERT INTO receiving (receivingnumber, transactiondate, ...) VALUES (createTransID('Receiving'), NOW(), ...);
END
createTransID
MySQL函数的定义如下:
CREATE FUNCTION createTransID(TransactionType VARCHAR(15), pStoreCode VARCHAR(15))
BEGIN
DECLARE returnValue VARCHAR(45);
CASE TransactionType
....
WHEN 'Receiving' THEN
SELECT CONCAT(Prefix,'-', LastSeries + 1) INTO returnValue FROM controlnumber WHERE StoreCode = pStoreCode FOR UPDATE;
...
END
RETURN returnValue;
END
现在我假设在使用FOR UPDATE
子句时,我锁定了controlnumber
表的记录,没有其他用户可以访问它因此,阻止
多个用户获得相同的lastSeries
值。但实际情况是,多个用户可以获得相同的lastSeries
值。我在这做错了什么?