#linq-to-sql #locking
#привязка к sql #блокировка
Вопрос:
Я застрял в решении о блокировке и подумал, что мог бы использовать ваш опыт.
Я хочу добавить новую строку в таблицу, и несколько потоков пытаются вставить эту новую строку в таблицу. Я хочу, чтобы удалялся только один из них. Во время выполнения вставки могут поступать запросы от других потоков на чтение некоторых данных из таблицы, и они должны быть успешными.
Какой был бы наилучший подход к блокировке для этого сценария? Эксклюзивные блокировки таблиц не будут работать, поскольку я хочу, чтобы запросы на чтение выполнялись успешно.
Спасибо xoxo
Ответ №1:
Позвольте базе данных выполнить работу — уникальный индекс ключа, чтобы победил первый вставляющий. Нет надежного способа обнаружить это до SubmitChanges, который не доставит вам больше проблем, чем вы начинаете.
Комментарии:
1. это не сработает в моей ситуации. Поэтому, пожалуйста, позвольте мне переформулировать это: я хочу удерживать блокировку в течение временного интервала, в течение которого вставки не могут быть выполнены, но выбор может быть выполнен. Что было бы лучшим способом для этого 🙂
Ответ №2:
Если вы хотите сериализовать вставки по определенному ключу, не прерывая чтение, и вы контролируете весь код, который будет это делать, взгляните на sp_getapplock . Сделайте имя applock соответствующим ключу, для которого вы пытаетесь заблокировать вставки, затем попросите параллельный код insert выполнить вызов sp_getapplock с таймаутом 0. Тот, который завершится успешно, должен проверить еще раз, чтобы убедиться, что запись не существует, удерживая блокировку, выполните вставку, затем снимите блокировку. Это некрасиво, это не быстро, но это делает то, что вы хотите. Вы также можете подключить sp_getapplock и связанные SPS к вашему DataContext, чтобы вы все еще могли вызывать их через L2S вместо отправки команды.