3

我需要在我的一个项目中使用batchId,一行或多行可以有单个batchId。因此,当我要从单个用户插入一堆 1000 行时,我会给这 1000 行一个单独的 batchId。这个batchId 是下一个自动增量batchId。

目前我为 unique_ids 维护一个单独的数据库表,并将最后一个 batchId 存储在那里。每当我需要在表中插入一批行时,我将 unique_ids 表中的 batchId 更新 1 并将其用于批量插入。

update unique_ids set nextId = nextId + 1 where `key` = 'batchId';

select nextId from unique_ids where `key` = 'batchId';

我调用了一个函数,该函数触发了两个查询,并返回了批处理的 nextId (batchId)。

这是我的 PHP 类和函数调用。我正在使用 ADODB,您可以忽略与 ADODB 相关的代码。

        class UniqueId
        {
                static public $db;

                public function __construct()
                {

                }

                static public function getNextId()
                {
                        self::$db = getDBInstance();        
                        $updUniqueIds = "Update unique_ids set nextId = nextId + 1 where `key` = 'batchId'";
                        self::$db->EXECUTE($updUniqueIds);

                        $selUniqueId = "Select nextId from unique_ids where `key` = 'batchId'";
                        $resUniqueId = self::$db->EXECUTE($selUniqueId);

                        return $resUniqueId->fields['nextId'];
                }
        }

现在,每当我需要下一个 batchId 时,我只需调用下面的代码行。

`$batchId = UniqueId::getNextId();`

但真正的问题是,当一秒钟内有数百个同时请求时,它会将相同的 batchId 分配给两个不同的批次。对我来说这是一个严重的问题。我需要解决这个问题。

请建议我该怎么做?我可以只限制这个类的一个实例,所以没有同时请求可以一次调用这个函数,并且永远不会给两个不同的批次提供一个 batchId。

4

2 回答 2

3

Have a look into atomic operations or transactions. It will lock the database and only allow one write query at any given instance in time.

This might affect your performance, since now other users have to wait for a unlocked database!

I am not sure what sort of support ADODB provides for atomicity though!

Basic concept is:

Acquire Lock
Read from DB
Write to DB with new ID
Release Lock

If a lock is already acquired, the script will be blocked (busy waiting) until it is released again. But this way you are guaranteed no data hazards occur.

于 2012-06-30T20:21:10.577 回答
-2

开始 tran 更新 选择 提交

这样,更新锁可以防止两个并发运行提取相同的值。

如果选择第一个,共享锁不会隔离两者

于 2013-02-09T02:28:46.060 回答