我在 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> id
(自动增量)& 测试
(int)。
当两个用户同时执行此代码时,我希望第一个交易锁定 test
表 选择
语句,以及第二笔交易以等待选择
对第一个要完成的语句。
如果一切顺利,则 ID
列应始终等于 test
列。
这可能吗?如果是这样,怎么样?
为了澄清,这是我想发生的事情:
- 两个用户
u1
和 u2
同时运行此代码, u1
运行了几微秒早期
U1
运行选择
语句,锁定表 test
-
u1
运行 insert
语句
u1
运行提交
语句,解锁表 test
-
u2
运行 select> select
语句,阅读新的 max(id)
之后插入
u1> u1
-
u2
运行 insert /code>语句
u2
运行提交
语句
I'm on MariaDB 10.6.5, and I have this code :
$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;");
The test
table has two columns : id
(auto incremented) & test
(int).
When two users execute this code at the same time, I want the first transaction to lock the test
table at the SELECT
statement and for the second transaction to wait at the SELECT
statement for the first one to finish.
If everything goes well, the id
column should always be equal to the test
column.
Is this possible ? And if so, how ?
For clarification, here's what I want to happen :
- Two users
U1
and U2
run this code at the same time, U1
runs it a few microseconds earlier
U1
runs the SELECT
statement, locking the table test
U1
runs the INSERT
statement
U1
runs the COMMIT
statement, unlocking the table test
U2
runs the SELECT
statement, reading the new MAX(id)
after the INSERT
of U1
U2
runs the INSERT
statement
U2
runs the COMMIT
statement
发布评论
评论(1)
您可以在开始时使用
get_lock
添加查询
do get_lock('lockname',30)
在开始时, do resable_lock('lockname')之后询问。因此,当用户1启动查询时,将设置锁定
lockname
,并且仅在完成后将其释放,如果用户2启动脚本do get_lock('lockname',30)
等待继续释放的锁。You can use
GET_LOCK
add the query
DO GET_LOCK('lockname', 30)
at the start andDO RELEASE_LOCK('lockname')
after the query.So when User 1 starts the query it sets the lock
lockname
and only releases it when finished, If User 2 starts the scriptDO GET_LOCK('lockname', 30)
waits for the lock to be released before continuing.