|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Други, кто может помочь - сир ву пле: Исходные данные: 1. Имеется SQL-таблица со столбцами ID и varchar(255); 2. N клиентов (с разных машин и несколько потоков с одной) могут делать SELECT и брать любую строку на обработку (т.е просто SELECT и результаты уже в других таблицах); Задача: Что сделать, чтобы клиент не мог брать строки, уже взятые другим клиентом? Существенных ограничений нет: можно создать доп. колонку, хранимую процедуру и т.п. В общем, всё во власти разработчика. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2010, 21:27 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Galant, Блокируем таблицу на чтение и запись. Получаем какую-то строку из тех для которых столбец Busy = 0. Выставляем ей Busy = 1. Разблокируем таблицу, после чего начнет работать следующий запрос в очереди, если такой имеется. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2010, 21:42 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Edd.Dragon, хочу узнать в какой субд так приходится делать? ... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2010, 22:12 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
web_foxEdd.Dragon, хочу узнать в какой субд так приходится делать? Сначала предложите свой способ. А то я других не знаю, как не дать заселектить то, что пять минут назад сосед заселектил. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.09.2010, 22:26 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
905Galant, SELECT ... FOR UPDATE http://www.postgresql.org/docs/8.4/static/sql-select.html Если бы автор конкретизировал задачу и уточнил, на сколько долго факт блокирования должен сохраняться, т.е. если ситуация сходная с созданием новой записи, то да, то что надо. А если необходима железная фиксация факта блокировки в момент блокировки на возможно длительное время и недопустим сброс этой информации в случае например приостановки SQL-сервера, тогда не пойдет. P.S.: Я кстати об этой конструкции давно забыл оказывается. Дело в том, что давно пишу на MySQL и заказчики требуют совместимости с нетранзакционным MyISAM, который естественно ее не поддерживает, в итоге давно с ней в коде не сталкивался. А транзакционные движки под MySQL поддерживают. А то по началу хотел было заявить, что в MySQL не пройдет этот "фокус" )))) ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2010, 12:41 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Кстати, насколько имеет значение количество незакрытых транзакций в конкретный момент времени? Есть ли какие-нибудь ориентировочные взаимосвязи количества заблокированных строк и производительности селектов? Для MS SQL или MySQL, Оракла - не важно, инфа будет полезной ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2010, 12:43 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Т.е. ответ на вопрос web_foxхочу узнать в какой субд так приходится делать? При использовании нетранзакционной модели, например в MySQL с движком MyISAM. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2010, 12:46 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Написать сохраненную процедуру в которой выполняется "пометка" таких записей для выборки: Код: plaintext 1. 2. 3.
И потом выбирать эти записи в любое время имея "отмеченные" Id. Если записи уже заняты, то благодаря условию Id not in (select ID from busy_ids where user != @user) второй раз занять их не получится. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2010, 14:13 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Edd.DragonТ.е. ответ на вопрос web_foxхочу узнать в какой субд так приходится делать? При использовании нетранзакционной модели, например в MySQL с движком MyISAM. Ясно. Медленно это всё будет работать. Человек, похоже, на ASP пишет, так что вряд ли это mysql, хотя он и не указал. Да и в вашем решении не нужно ничего блокировать, сразу апдейтить по условию. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.09.2010, 14:25 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Други, большое спасибо за ваши предложения! Действительно, забыл указать БД - это MS SQL Server 2008. Edd.Dragon , блокировать всю таблицу нельзя, т.к. другим клиентам тоже надо делать из неё SELECT. 905 , по всей видимости то, что нужно, но увы, есть только в Postgres. Alexsalog , решение элегантное, но в случае двух потоков на одном клиенте, боюсь, SELECT-ы будут пересекаться. В общем, как-то я подхожу к идее, что нужно писать раздатчик (но, ох, как не хочется). ... |
|||
:
Нравится:
Не нравится:
|
|||
12.09.2010, 13:17 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
GalantДруги, большое спасибо за ваши предложения! Действительно, забыл указать БД - это MS SQL Server 2008. Edd.Dragon , блокировать всю таблицу нельзя, т.к. другим клиентам тоже надо делать из неё SELECT. 905 , по всей видимости то, что нужно, но увы, есть только в Postgres. Alexsalog , решение элегантное, но в случае двух потоков на одном клиенте, боюсь, SELECT-ы будут пересекаться. В общем, как-то я подхожу к идее, что нужно писать раздатчик (но, ох, как не хочется). А чем не нравится "апдейтить по условию"? Два варианта: 1. update where "не занято" returning id - просто обновляете флаг. на выходе id строки, которую заняли. 2. update "устнавить id занимающего процесса" where "не занято". В решении Alexsalog селекты пересекаться не будут - они же выполняются атомарно с инсертами. Вам нужно серьёзно почитать мануал, т.к. есть непонимание азов. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.09.2010, 00:47 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Кстати, у решения Alexsalog огромный плюс - оно не обновляет исходную таблицу. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.09.2010, 00:50 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
Galant Edd.Dragon , блокировать всю таблицу нельзя, т.к. другим клиентам тоже надо делать из неё SELECT. Ну так блокировать только на время взятия же, а не на период занятости. Т.е. заблочили, взяли и пометили строку, разблочили - это миллисекунды. Дальше пошли следующие запросы. Через пол часа или через неделю проапдейтили строку попутно сняв флажок о занятости. Но раз MS SQL, то как и говорили выше - SELECT ... FOR UPDATE можно. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.09.2010, 11:32 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
web_fox , хорошо, проверю решение Alexsalog на реальных данных и займусь чтением мануала :) Edd.Dragon , в голову приходит только инструкция OUTPUT, которая вроде как даёт узнать что проапдейтилось. ... |
|||
:
Нравится:
Не нравится:
|
|||
13.09.2010, 12:31 |
|
Всю голову сломал
|
|||
---|---|---|---|
#18+
От чтения грязных данных на уровне сервера не защиты нет. На уровне приложения решить можно следующим образом: Читать всегда с уровнем изоляции read uncommitted, при необходимости блокировки набора записей или для чтения "чистых" данных хинтами повышать уровень изоляции до read committed. Написать свой механизм блокировок или версионности тоже можно :), боюсь пойдете дорогой разочарований. В любом случае успехов. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.09.2010, 15:40 |
|
|
start [/forum/topic.php?fid=33&fpage=30&tid=1548217]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
39ms |
get topic data: |
13ms |
get forum data: |
3ms |
get page messages: |
51ms |
get tp. blocked users: |
2ms |
others: | 10ms |
total: | 148ms |
0 / 0 |