我在MariaDB 10.6.5上,我有以下代码:
$pdo->query("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;");
$pdo->query("SET autocommit = 0;");
try
{
$max_id = $pdo->query("SELECT MAX(id) FROM test")->fetchColumn();
sleep(3);
$insert_sql = $pdo->prepare("INSERT INTO test(test) VALUES(:test)");
$insert_sql->execute(['test' => $max_id + 1]);
}
catch (Throwable $e)
{
$pdo->query("ROLLBACK;");
}
$pdo->query("COMMIT;");
test
表有两列:id
(自动递增)和test
(整数)。
当两个用户同时执行此代码时,我希望第一个事务在SELECT
语句处锁定test
表,而第二个事务在SELECT
语句处等待第一个事务完成。如果一切顺利,则id
列应始终等于test
列。
这是可能的吗?如果是的话,怎么可能?
为了澄清,我希望发生以下情况:
- 两个用户
U1
和U2
同时运行此代码,U1
提前几微秒运行它 U1
运行SELECT
语句,锁定表test
U1
运行INSERT
语句U1
运行COMMIT
语句,从而解锁表test
U2
运行SELECT
语句,在U1
的INSERT
之后读取新的MAX(id)
U2
运行INSERT
语句U2
运行COMMIT
语句
1条答案
按热度按时间t3psigkw1#
您可以使用
GET_LOCK
在开始处添加查询
DO GET_LOCK('lockname', 30)
,并在查询之后添加DO RELEASE_LOCK('lockname')
。因此,当用户1启动查询时,它会设置锁
lockname
,并仅在完成时释放它。如果用户2启动脚本DO GET_LOCK('lockname', 30)
,则会在继续之前等待锁被释放。