У меня есть таблица, в которой хранятся конфиденциальные данные, и мне нужно позаботиться о том, чтобы только один сеанс мог читать / писать в определенной строке.
В моей таблице 2 столбца id (int) первичный количество (целое) индекс
поэтому я хочу заблокировать таблицу, но только одну строку что-то вроде
LOCK TABLEROWS `mytable` WRITE WHERE `id` = 1
Я использую pdo и startTransaction, не помешает другим сеансам читать / писать в это время
Я прочитал документацию InnoDB, но не запустил ее
Обновлено:
$_PDO->exec('START TRANSACTION');
$_PDO->query('SELECT * FROM `currency` WHERE `id` = '.$userid.' FOR UPDATE');
//maybe do update or not check if
$_PDO->exec('COMMIT');
так это все, что мне нужно сделать?
Но этот блок не читается? это то что мне нужно
Посмотрите на stackoverflow.com/questions/44440152/…
проверьте обновление, пожалуйста






В приведенном вами примере другие сеансы, выполняющие SELECT...FOR UPDATE, будут ждать вашего COMMIT. Блокировки, запрошенные SELECT...FOR UPDATE, являются блокировками эксклюзивный, поэтому только один сеанс за раз может получить блокировку. Поэтому, если ваш сеанс удерживает блокировку, другие сеансы будут ждать.
Вы не можете заблокировать неблокирующее чтение. Другой сеанс может запустить SELECT без условия блокировки и по-прежнему читать данные. Но они не могут ни обновить данные, ни запросить блокирующее чтение.
В качестве альтернативы вы можете сделать каждый запрос сеанса блокировкой таблицы с помощью ТАБЛИЦЫ БЛОКИРОВКИ, но вы сказали, что хотите блокировки в масштабе строки.
Вы можете создавать свои собственные пользовательские блокировки с помощью функции GET_LOCK (). Это позволяет сделать отдельную блокировку для каждого идентификатора пользователя. Если вы сделаете это для всего кода, который обращается к таблице, вам не нужно использовать FOR UPDATE.
$lockName = 'currency' . (int) $userid;
$_PDO->beginTransaction();
$stmt = $_PDO->prepare("SELECT GET_LOCK(?, -1)");
$stmt->execute([$lockName]);
$stmt = $_PDO->prepare('SELECT * FROM `currency` WHERE `id` = ?');
$stmt->execute([$userid]);
//maybe do update or not check if
$_PDO->commit();
$stmt = $_PDO->prepare("SELECT RELEASE_LOCK(?)");
$stmt->execute([$lockName]);
Это зависит от взаимодействия всего клиентского кода. Всем им необходимо получить блокировку, прежде чем они будут работать с заданной строкой. Вы можете использовать SELECT...FOR UPDATE или GET_LOCK().
Но вы не можете заблокировать клиентов, которые хотят выполнять неблокирующее чтение с SELECT.
Используйте блокировку намерений, например
SELECT ... FOR UPDATEdev.mysql.com/doc/refman/5.5/en/…