在一个原子操作中从InnoDB表中进行选择和截断的最佳方法是什么?

问题描述 投票:0回答:2

我想使用SELECT从InnoDB表中读取数据,然后在一个操作中使用TRUNCATE截断它,以便其他查询必须等待TRUNCATE操作完成才能修改表。最好的方法是什么?据我了解,表锁不适用于TRUNCATE。但是从我的测试来看,事务do使用TRUNCATE。但是,仅在隔离级别为SERIALIZABLE的情况下,才能保证事务不重叠。

我正在使用PHP和MySQLi。默认隔离级别是REPEATABLE READ,所以我将其更改为SERIALIZABLE,以防止在事务完成之前并发查询修改表:

$mysqli->query("SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE");

$mysqli->begin_transaction();

// Select statements reading from `my_table`

$mysqli->query("TRUNCATE `my_table`");

$mysqli->commit();

这似乎工作正常。我只是想知道是否有更好的方法。

php mysql concurrency innodb atomicity
2个回答
0
投票
假设您已打开错误报告:

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

您可以使用事务一步来读取和删除数据。我不确定为什么要设置不同的隔离模式,但是我认为您不需要它。如果我理解正确,它将锁定行并防止删除。 

您不能使用TRUNCATE,因为它是DDL语句,并且不适用于事务。 DELETE较慢,但可以回滚。

try { // Start transaction $mysqli->begin_transaction(); $result = $mysqli->query('SELECT * FROM my_table'); $mysqli->query('DELETE * FROM my_table'); // Commit changes $mysqli->commit(); } catch (\Throwable $e) { // Something went wrong. Rollback $mysqli->rollback(); throw $e; }


0
投票
[GET_LOCK()RELEASE_LOCK()与事务等正交(极少使用,但是您的情况可能需要它们。)]
© www.soinside.com 2019 - 2024. All rights reserved.