使用隔离级别可序列化时,重复值插入

时间:2018-07-04 06:42:48

标签: sql sql-server

我有一个表SalesOrders,其中保存着特定salesOrder的{​​{1}}。因为我跟踪许多组织的发票,所以该表还包含一个organization。对于每个组织,invoice应该增加1,并且没有间隔。

我需要做一个

salesOrder

但是这个isn't safe没有INSERT INTO SalesOrders (...) VALUES (... , SELECT MAX(salesOrder) + 1 FROM SalesOrders WHERE organization = @org) 或同等的锁。

但是,当我用隔离级别包装事务时,我看到表中插入了重复的值。我不明白为什么:事务隔离级别应防止这种情况发生?

我正在使用(PHP PDO)的代码块如下。

作为该查询的结果,我为什么会在表中看到重复的ISOLATION LEVEL SERIALIZABLE


salesNumbers

更多信息:

所讨论的表有〜4300行,具有11个重复的值。例如:

$db->query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');

$db->beginTransaction();
$query = '
    SELECT  MAX(orderNumber) AS number
    FROM    SalesOrders
    WHERE   organization = :organization';

$params = array(':organization' => $organizationId);

$statement = $db->prepare($query);
$statement->execute($params);

// Sometimes we have no results at all [no sales for a particular organization]
$existing = $statement->fetchAll();
$newNumber = (sizeof($existing) == 1 ? $existing[0]['number'] + 1 : 1);

$createQuery = 'INSERT INTO SalesOrders (
                    organization,
                    orderNumber,
                    invoice
                ) VALUES (
                    :organization,
                    :number,
                    :invoice
                )';
$createParams = array(
    ':organization' => $organizationId,
    ':number' => $newNumber,
    ':invoice' => $invoiceId
);

$secondStatement = $db->prepare($createQuery);
$secondStatement->execute($createParams);

$db->commit();

0 个答案:

没有答案