29.07.2010, 14:24 | #1 |
Участник
|
Можно ли сделать блокировку на чтения таблицы.
То есть пока один пользователь берет параметры из таблицы, на основании которых будет делать дальнейшее действие. Второй не смог прочитать из таблицы. Т.е. что бы оба не прочитали одно и тоже. Можно ли сделать обычную транакцию? типа начать транзакцию выполнение кода закончить транзакцию функция LOCKTABLE я так понимаю работает на запрет ЗАПИСИ в таблицу. |
|
29.07.2010, 14:45 | #2 |
Участник
|
Запретить чтение из таблицы на уровне SQL можно наверное только отбором прав.
Запретить читать другими способами скорее всего нет. Что конкретно надо? Чтобы пользователь не мог увидеть инфу, которую модифицирует в данный момент другой пользователь? Еще додумал. Делать это так не нужно. Не правами.. Пусть пользователь, считавший запись для того, чтобы что-то с ней делать вписывает в поле этой записи свой БД логин. На форме поставить фильтр на поле СВОЙ ЛОГИН | ПУСТО. Тогда другой пользователь не увидит "зарезервированную" другим пользователем запись. |
|
29.07.2010, 15:03 | #3 |
Участник
|
не совсем то.
надо чтобы второй пользователь стал читать данные, только после того как их прочитал первый. то есть первый прочитал - внес изменения, потом второй на основе изменений прочитал, внес свои. Что бы не получилось так, что оба прочитали одно и тоже и пытаются внести одни и те же изменения. |
|
29.07.2010, 15:43 | #4 |
Участник
|
Цитата:
Запомните, если какое-то решение кажется абсурдным или нереально сложным, то это неправильное решение. В случае с навиженом это работает точно. А еще можно внутренним регламентом разграничить сущности, с которыми работают пользователи по какому-либо признаку, чтобы один работал со своим куском, а другой со своим. То, КАК вы хотите нельзя сделать на уровне БД SQL. |
|
29.07.2010, 16:04 | #5 |
Участник
|
пользователи работают с одним и тем же куском.
я так понимаю, на запись в таблицу блокировку поставить можно, а на чтение нет? |
|
29.07.2010, 17:33 | #6 |
Участник
|
Цитата:
Открыл пользователь форму, в ней наверное не одна запись. Другому пользователю нельзя все эти записи читать? А если первый пользователь заснет на 2 часа - жара же на улице, всему холдингу в носу ковырять? Рассмотрите вариант с "резервированием" строки под редактирование (как с Примен ID при применении - ставит пользователь в поле свой БД логин и все, другой при работе с такой записью - попытке редакции - получит предупреждение и править ее сможет только после того как первый освободит MODIFYем) |
|
30.07.2010, 10:21 | #7 |
Участник
|
не тут не совсем так.
я не имел ввиду под пользователем человека. "типа открыл форму и читает, а второй не может даже видеть в этот момент эту таблицу." просто выполняется код. его запускает первый пользователь, этот код на основе значений в таблице делает запись. и второй пользователь запускает этот же код. надо что бы в тот момент когда выполняется код, запущенный первым польователем, код запущенный вторым пользователем не выполнялся. точнее, чтобы он подождал, когда первый код закончится и сделает изменения, а потом уже второй может производить чтение. |
|
30.07.2010, 11:11 | #8 |
Участник
|
Создайте табличку:
НомерОбъекта Функция в объекте ТаблицаДляБлокировки В нее пишите какой объект заблокировал таблицу. И после окончания блокировки удаляйте из нее. И при запуске функции проверяйте, есть ли в этой таблице заблокироаванные данные. |
|
30.07.2010, 11:21 | #9 |
Administrator
|
имхо, крайне безумная задача.
никакое рациональное решение не подойдет. я б тупо НИЧЕГО бы не делал. |
|
30.07.2010, 12:47 | #10 |
Участник
|
А разве уровень изоляции транзакций уже отменен? Делайте LOCKTABLE, а в функциях, которые читают данные делайте принудительное повышение уровня изоляции.
Это может быть как LOCKTABLE, так и другие способы (зависит от типа объекта). Цитата:
функция LOCKTABLE я так понимаю работает на запрет ЗАПИСИ в таблицу
LOCKTABLE и последующий GET ставит блокировку на эту запись, и если другой пользователь попробует сделать тоже самое (LOCKTABLE, GET), то будет ждать пока завершится транзакция первого пользователя. Это для SQL. Для нативной базы все несколько по-другому и проще. |
|
03.08.2010, 14:28 | #11 |
Участник
|
Можно ещё попробовать перед началом "чтения" прописать SELECTLATESTVERSION, .т.е хотя бы увеличить вероятность того, что "второй пользователь" прочитает свежие данные в БД, внесённые "первым пользователем".
|
|
05.08.2010, 07:50 | #12 |
Участник
|
Alterant дело говорит, в начале алгоритма пиши:
Rec.LOCKTABLE; Rec.FINDLAST; И тогда этот алгоритм никогда не будет выполняться на двух клиентах одновремено. LOCKTABLE защищает от "грязного" чтения. Я так понял тебе это и нужно. Пока один пользователь меняет данные в табличке, то верить этим данным нельзя, пока этот пользовтель не закончит. |
|
05.08.2010, 11:31 | #13 |
Участник
|
FINDLAST я бы не рекомендовал. FINDLAST блокирует только последнюю запись и возможность добавления новых. Записи из середины он не блокирует (если не было эскалации). Если нужно обеспечить целостность конкретной записи - GET, если на добавление - FINDLAST.
|
|
06.08.2010, 13:04 | #14 |
Участник
|
И ещё, как бы ты не блокировал,формочка всёравно отобразит строки таблицы.
Суть в том, что нельзя заблокировать одну и туже строку разными клиентсми. Используй это свойство для разграничения доступа. |
|