我需要在我的项目中使用batchId,一行或多行可以有单个batchId。因此,当我要从单个用户插入一堆1000行时,我将为这1000行提供一个batchId。这个batchId是下一个autoincrement 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分配给两个不同的批次。
答案 0 :(得分:3)
查看原子操作或事务。它将锁定数据库,并且只允许在任何给定实例上进行一次写入查询。
这可能会影响您的性能,因为现在其他用户必须等待解锁的数据库!
我不确定ADODB为atomicity提供了哪种支持!
基本概念是:
Acquire Lock
Read from DB
Write to DB with new ID
Release Lock
如果已获取锁定,则将阻止脚本(忙等待),直到再次释放。但是这样可以保证不会发生数据危害。
答案 1 :(得分:-2)
开始tran 更新 选择 提交
这样,更新锁会阻止两个并发运行提取相同的值。
如果先选择,则共享锁不会隔离两个