Есть таблица с кейвордами и ссылками. На каждый кейворд 30-50 ссылок.
Нужно забрать по заданному кейворду все ссылки, но при этом отметить, что они забраны.
Делаю двумя последовательными запросами.
SELECT url FROM links WHERE post = '0' AND keywords = 'key';
UPDATE links SET post='1' WHERE keywords = 'key';
Здравствуйте, Volgare, Вы писали:
V>Нужно забрать по заданному кейворду все ссылки, но при этом отметить, что они забраны. V>Делаю двумя последовательными запросами. V>
V>SELECT url FROM links WHERE post = '0' AND keywords = 'key';
V>UPDATE links SET post='1' WHERE keywords = 'key';
V>
Здравствуйте, Volgare, Вы писали:
V>Я пытаюсь так V>
V>UPDATE links SET post='1' WHERE url in
V>(SELECT url FROM links WHERE post = '0' AND keywords = 'key');
V>
V>Но лезет ошибка.
какая?
V>Проблема в том, что я ещё работаю с mySQL через специфичный C# софт
Ну так нужно было с этого начинать
Как это делается в mySQL — я, к сожалению, не в курсе.
Если в MySql к 2017 году таки завезли транзакции, то сделать это можно хоть двумя, хоть десятью запросами — в рамках одной транзакции. А особо специфичный софт между вашей программой и БД надо просто убрать, если он не позволяет просто отправлять запросы.
V>UPDATE links SET post='1' WHERE url in
V>(SELECT url FROM links WHERE post = '0' AND keywords = 'key');
V>
На вид этот update ничего кроме кол-ва обновленных строк не вернет.
Вам правильно посоветовали Select ... For Update;
MySQL умеет Select For Update — конкурентные читатели первого Select не начнут читать и будут ждать пока не отработает второй Update:
START TRANSACTION;
SELECT url FROM links WHERE post = '0' AND keywords = 'key' for update;
UPDATE links SET post='1' WHERE keywords = 'key';
COMMIT;
Здравствуйте, Volgare, Вы писали:
V>Но если в многопотоке, то возникают накладки, ключ берут сразу несколько потоков в паузе между запросами SELECT и UPDATE.
В некоторых СУБД (Postgres, Oracle) есть возможность через RETURNING получить строки из UPDATE. То есть можно обойтись одним UPDATE.
Здравствуйте, amironov79, Вы писали:
A>В некоторых СУБД (Postgres, Oracle) есть возможность через RETURNING получить строки из UPDATE. То есть можно обойтись одним UPDATE.
Да, по блокировкам этот вариант не будет отличаться от варианта с FOR UPDATE, соседний транзакция будет блокироваться на UPDATE, пока не завершится текущая.
Здравствуйте, Volgare, Вы писали:
V>Есть таблица с кейвордами и ссылками. На каждый кейворд 30-50 ссылок. V>Нужно забрать по заданному кейворду все ссылки, но при этом отметить, что они забраны. V>Делаю двумя последовательными запросами. V>
V>SELECT url FROM links WHERE post = '0' AND keywords = 'key';
V>UPDATE links SET post='1' WHERE keywords = 'key';
V>
А вот ещё такая задачка
Нужно сделать SELECT keywords FROM links WHERE post = '0';
но при этом взять, скажем, только 100 первых рядов удовлетворяющих условию post = '0' и из этих 100 взять только 1 случайный ряд.
И всё это одним запросом.
Вот такое необычное желание))