Нужно написать программку на VC++, которая бы обеспечивала доступ к базе данных, но основная сложность, для меня, представляет синхронизация данных в этой БД.
Т.е. если несколько юзеров будут INSERT'ить SELECT'ить UPDATE'ить одну и ту же базу,
одновременно, у некоторых будут неправильные данные.
Число юзеров не более 5 человек.
Как по науке решается вопрос о синхронизации? Может какие-то примеры?
И какую БД лучше использовать для этих нужд?
Здравствуйте Grog13M, Вы писали:
GM>Приветствую.
GM>Нужно написать программку на VC++, которая бы обеспечивала доступ к базе данных, но основная сложность, для меня, представляет синхронизация данных в этой БД.
GM>Т.е. если несколько юзеров будут INSERT'ить SELECT'ить UPDATE'ить одну и ту же базу, GM>одновременно, у некоторых будут неправильные данные.
Нет конечно. Если база не совсем г*. Рекомендую почитать что-нибудь типа "Реляционные БД для чайников". GM>Число юзеров не более 5 человек.
GM>Как по науке решается вопрос о синхронизации? Может какие-то примеры?
Главное ключевое слово — ACID (Atomicity, Consisteny, Isolation, Durability). Второе ключевое слово — transaction. GM>И какую БД лучше использовать для этих нужд?
Ту, которая поддерживает транзакции. Почти все современные СУБД это делают. Никаких усилий (почти) по синхронизации приложений не потребуется.
GM>Спасибо.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
GM>>Как по науке решается вопрос о синхронизации? Может какие-то примеры? S>Главное ключевое слово — ACID (Atomicity, Consisteny, Isolation, Durability). Второе ключевое слово — transaction. GM>>И какую БД лучше использовать для этих нужд? S>Ту, которая поддерживает транзакции. Почти все современные СУБД это делают. Никаких усилий (почти) по синхронизации приложений не потребуется.
Ага, я понял, принцип транзакции "либо все, либо ничего"
После того как юзер сделал COMMIT, то любые другие юзеры при SELECT'ах увидят измененное состояние, если СЕЛЕКТ был после КОММИТА и предыдущее состояние если до?
Т.е. в самом приложении ничего по синхронизации данных делать не надо? Или?
Порекомендуйте, пожалуйста, какую-нибудь простенькую БД, с возможностью транзакций.
Стоять это все будет по Win2000 или WinXP.
Здравствуйте Grog13M, Вы писали:
GM>Здравствуйте Sinclair, Вы писали:
GM>>>Как по науке решается вопрос о синхронизации? Может какие-то примеры? S>>Главное ключевое слово — ACID (Atomicity, Consisteny, Isolation, Durability). Второе ключевое слово — transaction. GM>>>И какую БД лучше использовать для этих нужд? S>>Ту, которая поддерживает транзакции. Почти все современные СУБД это делают. Никаких усилий (почти) по синхронизации приложений не потребуется.
GM>Ага, я понял, принцип транзакции "либо все, либо ничего" GM>После того как юзер сделал COMMIT, то любые другие юзеры при SELECT'ах увидят измененное состояние, если СЕЛЕКТ был после КОММИТА и предыдущее состояние если до?
Ну, то что на самом деле увидят усеры сильно зависит от так называемого "уровня изоляции" транзакций, в которых они находятся и от используемой модели поддержки кислотности. Например, при дефолтной изоляции (Read Committed) в MS SQL Server усеры, пытающиеся сделать селект по данным, которые сейчас кто-то пишет, будут вынуждены ждать коммита. А вот в interbase, например. они действительно увидят предыдущее состояние.
GM>Т.е. в самом приложении ничего по синхронизации данных делать не надо? Или?
Да. Ничего делать не надо. Прежде всего потому, что дело это дюже сложное, и в стандартные БД встроено более чем достаточно возможностей для поддержки всех типичных сценариев синхронизации.
GM>Порекомендуйте, пожалуйста, какую-нибудь простенькую БД, с возможностью транзакций. GM>Стоять это все будет по Win2000 или WinXP.
Гм. Увы, я не спец в этих вопросах. По идее, MS Access должен это все уже уметь — лень читать доку.
А так, под виндою, я считаю, лучче MS SQL нету. Тем более теперь он даже в CE варианте есть, то ись совсем нетребовательный зверек.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте Grog13M, Вы писали:
GM>Здравствуйте Sinclair, Вы писали:
GM>Порекомендуйте, пожалуйста, какую-нибудь простенькую БД, с возможностью транзакций. GM>Стоять это все будет по Win2000 или WinXP.
я бы так распределил (любое деление, конечно, условно):
персональные БД — MSAccess
начального уровня — mySQL
среднего — Interbase или Sybase Anywhere
высокого — Sybase Enterprise, MSSQL
очень высокого — Oracle, Progress
Здравствуйте Grog13M, Вы писали:
GM>Здравствуйте Sinclair, Вы писали:
GM>Порекомендуйте, пожалуйста, какую-нибудь простенькую БД, с возможностью транзакций. GM>Стоять это все будет по Win2000 или WinXP.
В твоем случае лучший вариант Interbase, в кратце почему:
1. На небольшом числе активных коннектов (до 100 ) очень быстрая (ИМХО сделает ORACLE) и надежная СУБД, работает с большимими объемами данных > 2Гб (на два куска)
2. Кросс платформенность, сразу же рекомендую переходить на Linux там есть Interbase classic server.
3. Легко настраивается, практически plug&play.
4. Поддерживает и наиболее соответствует T-SQL.
5. Если Делфи-ец — есть в VCL компоненты прямого доступа IBX, для C/С++ precompiler или писать на API что тоже клево.
6. рускоязычный сайт ib.demo.ru c Димой Кузьменко /*мое почтение*/ (но кажется он сменил положение)
7. У 6-й версии открыт исходный код.
8. 6-я версия бесплатна
учитывая все это можно разработать качественную клиент-серверную БД с очень низкой себестоимостью (IB_CS_LI_6.x + RH Linux 7.2)
минусы:
1. Изначально развивалась как малая СУБД, отсюда и все минусы (не использует SMP под Вынь и др.)
Здравствуйте Sinclair, Вы писали:
S>Здравствуйте Grog13M, Вы писали:
GM>>Здравствуйте Sinclair, Вы писали:
GM>>>>Как по науке решается вопрос о синхронизации? Может какие-то примеры? S>>>Главное ключевое слово — ACID (Atomicity, Consisteny, Isolation, Durability). Второе ключевое слово — transaction. GM>>>>И какую БД лучше использовать для этих нужд? S>>>Ту, которая поддерживает транзакции. Почти все современные СУБД это делают. Никаких усилий (почти) по синхронизации приложений не потребуется.
GM>>Ага, я понял, принцип транзакции "либо все, либо ничего" GM>>После того как юзер сделал COMMIT, то любые другие юзеры при SELECT'ах увидят измененное состояние, если СЕЛЕКТ был после КОММИТА и предыдущее состояние если до? S>Ну, то что на самом деле увидят усеры сильно зависит от так называемого "уровня изоляции" транзакций, в которых они находятся и от используемой модели поддержки кислотности. Например, при дефолтной изоляции (Read Committed) в MS SQL Server усеры, пытающиеся сделать селект по данным, которые сейчас кто-то пишет, будут вынуждены ждать коммита. А вот в interbase, например. они действительно увидят предыдущее состояние.
GM>>Т.е. в самом приложении ничего по синхронизации данных делать не надо? Или? S>Да. Ничего делать не надо. Прежде всего потому, что дело это дюже сложное, и в стандартные БД встроено более чем достаточно возможностей для поддержки всех типичных сценариев синхронизации.
GM>>Порекомендуйте, пожалуйста, какую-нибудь простенькую БД, с возможностью транзакций. GM>>Стоять это все будет по Win2000 или WinXP. S>Гм. Увы, я не спец в этих вопросах. По идее, MS Access должен это все уже уметь — лень читать доку. S>А так, под виндою, я считаю, лучче MS SQL нету. Тем более теперь он даже в CE варианте есть, то ись совсем нетребовательный зверек.
А скажите, поддерживает ли механизм транзакций такие возможности:
представим себе две связанные таблицы (один-ко-многим), допустим, накладная — перечень товаров. Один юзер выбрал запись с накладной номер NN, считал через SELECT перечень находящихся в ней товаров и редактирует этот перечень.
Второй юзер, не ведая того, что накладную NN выбрал первый, тоже считал ее и редактирует, хотя вроде как и не имеет на это право.
Есть ли возможность сообщить юзеру №2, что, хотя он прочел накладную NN, он не имеет право ее редактировать? Есть ли возможность сообщить юзеру №2, кто в данный момент редактирует накладную NN из других пользователей?
Или механизм транзакций может только сообщить юзеру №2 при сохранении накладной, что все изменения, которые он сделал, недействительны, так как данная запись "была изменена другим пользователем"?
Здравствуйте Al-Ko, Вы писали:
AK>А скажите, поддерживает ли механизм транзакций такие возможности:
AK>представим себе две связанные таблицы (один-ко-многим), допустим, накладная — перечень товаров. Один юзер выбрал запись с накладной номер NN, считал через SELECT перечень находящихся в ней товаров и редактирует этот перечень. AK>Второй юзер, не ведая того, что накладную NN выбрал первый, тоже считал ее и редактирует, хотя вроде как и не имеет на это право.
AK>Есть ли возможность сообщить юзеру №2, что, хотя он прочел накладную NN, он не имеет право ее редактировать? Есть ли возможность сообщить юзеру №2, кто в данный момент редактирует накладную NN из других пользователей?
AK>Или механизм транзакций может только сообщить юзеру №2 при сохранении накладной, что все изменения, которые он сделал, недействительны, так как данная запись "была изменена другим пользователем"?
Значит, так. Вышеобсужденная кислотность (ACIDity) может достигаться различными способами. В основном различают два: pessimistic locking и optimistic locking.
Суть пессимистичной блокировки состоит в тоследующем: мы предпочитаем "раннее оповещение" о возможных конфликтах. Поэтому объект, к которому осуществляется доступ, блокируется таким образом, чтобы никто другой не мог выполнить конфликтующую операцию. То есть мы зашли в домик, дверь заперли и сидим, пока не закончим. Тот, кто попытается зайти туда же, получит от ворот поворот. В вышеприведенном примере это означает, что второй юзер просто не сможет отредактировать накладную NN.
Блокировки в такой системе бывают трех типов: Shared, Update, Exclusive.
Когда клиент (точнее, транзакция) пытается запросить какой-либо вид лока на определенный объект, то успех или неуспех операции зависит от наличия существующего лока на тот же объект, созданного другой транзакцией. В следующей таблице в столбцах идут существующие локи, а каждая строка соответствует запрашиваемому типу:
Плюсик означает, что операция будет успешна. Как видно, матрица имеет диагональный вид. Это естественно — совместимость локов штука симметричная. Смысл этой таблички в том, что те, кто хотят читать данные, получают перед этим shared lock. Из таблички видно, что они обломятся только в том случае, если кто-то уже захватил exclusive лок — это означает, что в данные прямо сейчас идет запись, и читать их нельзя. Все остальные виды локов, имеющиеся на объекте, не мешают нашему чтению.
Те, кто собирается писать данные, должны сначала получить exclusive lock, чтобы убедиться, что они никому не мешают. Такой лок не совместим ни с кем, и может быть выдан только один одновременно.
Промежуточный update lock введен в систему для того, чтобы решить такую проблему: когда кто-то сначала читает данные, а потом пытается их же писать. Если две таких транзакции выполняются одновременно (а это весьма вероятно, т.к. множество клиентов скорее всего будут выполнять однотипные действия), то у них будет хороший шанс зажать друг друга в угол. Дело в том, что если запрошенный лок конфликутет с уже имеющимися, то по умолчанию транзакция неопределенно долго ожидает снятия локов. Так что две транзакции спокойно получат по shared локу и каждая попытается сконвертировать его в exclusive. Но каждая сможет продолжить свою работу только после того, как другая отпустит shared lock. Итого — deadlock. Упс. Всех расстрелять.
Получение сразу exclusive лока не есть хорошо, поскольку если мы первые 90% процентов времени в транзакции тратим на чтение и 10% на запись, то 9/10 времени мы не даем другим доступа безо всякой к тому причины.
Глядя на схему совместимости update лока, можно понять для чего он предназначен. Он все еще дает остальным читать данные, но не даст никому ни писать, ни получить аналогичный лок, гарантируя успешное получение exclusive лока позднее.
Итак, с вами были пессимистичные блокировщики.
Далее в нашей программе — optimistic locking.
Эта стратегия на первый взгляд не похожа на блокировку вообще. Дело в том, что мы "запираем" данные только в момент commit транзакции, а длительные подготовки к этому моменту делаются безо всяких проверок конкурирующего доступа.
Ключевым фактором в оптимистичной блокировке является детектирование произошедших изменений.
Алгоритм коммита таков:
1. Проверить все данные, которые мы читали в транзакции, на наличие изменений с тех пор.
2. Если обнаружены изменения, то результат наших действий некорректен. Производим rollback, т.е. все изменения отменяются.
3. Если изменений не обнаружено, то можно сохранять изменения транзакции, делая их видимыми для окружающих.
Реализация этого алгоритма сделана по разному в разных системах. Например, в Interbase в саму структуру базы встроено отслеживание изменений в читаемых кем-либо данных. В MS SQL Server это делается при помощи сочетания timestamp-полей, которые гарантированно изменяют свое значение при хаписи в таблицу, и кратковременных пессимистичных блокировок в момент коммита (надо сказать, что сам сервер предоставляет только самый низкий уровень поддержки. Чтобы реализовать OL-систему на его основе, надо изрядно попотеть).
Резюме:
В вышеописанной ситуации картина для пользователей будет примерно такой, в зависимости от типа используемых блокировок:
1. Пессимистичные блокировки:
1.1. Немедленный откат: Потльзователь 2 получает при попытке зачитать накладную Упс! Объект зблокирован.
1.2. Бесконечное ожидание У Пользователя 2 прога виснет при чтении до тех пор, пока Пользователь 1 не сохранит/отменит свои изменения. После этого Пользователь 2 увидит корректное финальное состояние данных.
1.3. Конечное ожидание. Прога повисит некоторое время, и либо выпадет результат 1.1, либо 1.2, в зависимости от тормознутости Пользователя 1.
Резюме пессимистичных блокировок: Кто первым встал, того и тапки. Все проблемы касаются только Пользователя 2.
2. Оптимистичные блокировки:
Оба Пользователя увидят одну и ту же версию накладной — исходную. Дальнейший результат зависит от того, в каком порядке и какие действия они выполняют:
2.1. Пользователь 2 всего лишь хотел посмотреть чегой-то в этой накладной. Увидел, закрыл. Пользователь 1 ничего не заметил
2.2. Пользователь 2 шустро что-то поменял и сохранил накладную. Пользователь 1 при попытке сохранить накладную (но не раньше!) увидит "Изменения недействительны"
2.3. Пользователь 2 залез и начал что-то менять. Пользователь 1 сохранил накладную. Пользователь 2 при попытке сохранить получит тот же отказ "Изменения недействительны".
Таким образом:
1. При пессимистичных блокировках придется ждать, пока объект отпустят, даже если хотелось "всего лишь посмотреть"
2. При оптимистичных блокировках нет никакой возможности проверить, а не случилось ли страшное (кроме как истерично сохраняться каждые 20 секунд, надеясь подловить конкурента)
На самом деле, привденный пример реализации пессимизма слишком мрачен — при правильном управлении блокировками (shared->update->exclusive) можно добится высокой степени одновременности работы, все еще избегая потери изменений. Просто я и так чего-то увлекся... Люблю я эти вещи... транзакции, блокировки... кэши, индексы... оптимизация планов запросов, двухфазный коммит...
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте Sinclair, Вы писали:
S>Здравствуйте Al-Ko, Вы писали:
AK>>А скажите, поддерживает ли механизм транзакций такие возможности:
AK>>представим себе две связанные таблицы (один-ко-многим), допустим, накладная — перечень товаров. Один юзер выбрал запись с накладной номер NN, считал через SELECT перечень находящихся в ней товаров и редактирует этот перечень. AK>>Второй юзер, не ведая того, что накладную NN выбрал первый, тоже считал ее и редактирует, хотя вроде как и не имеет на это право.
AK>>Есть ли возможность сообщить юзеру №2, что, хотя он прочел накладную NN, он не имеет право ее редактировать? Есть ли возможность сообщить юзеру №2, кто в данный момент редактирует накладную NN из других пользователей?
AK>>Или механизм транзакций может только сообщить юзеру №2 при сохранении накладной, что все изменения, которые он сделал, недействительны, так как данная запись "была изменена другим пользователем"?
Извините за SKIPPED — это самая классная статья по транзакциям, которая мне попадалась. Но...
Что pessimistic, что optimistic — такая реализация одновременного доступа только лишь с помощью транзакций не позволяет "спокойно" работать с такой простейшей базой данных, которая приведена в моем примере. У нас в сети всего три (очень редко четыре) компьютера, и между ними иногда происходят конфликты, связанные с одновременным доступом. Правильно, или ты ждешь неизвестно сколько, пока запись не освободится, или ты получаешь откат после вдумчивого редактирования накладной с пояснением, что ты не имеешь, оказывается, право эту накладную редактировать.
Пришлось искать какой-то выход из положения. Ничего лучшего не придумав, в базу данных пришлось ввести служебную таблицу (назовем ее условно LOCKER), которая содержит в себе все имеющиеся на данный момент блокировки. Она выглядит примерно так:
User Table Info(номер блокированного документа)
=================================================================
1 INVOICE 56
1 ORDER 12
2 INVOICE 55
3 INVOICE 57
итак, пользователь 1 зашел в накладную 56. При этом он может редактировать эту накладную, либо пить кофе в другой комнате (что тоже иногда встречается). Пользователь N, заходя в накладную 56, получает информацию из таблицы LOCKER, что накладная 56 заблокирована пользователем 1. Он может читать из накладной 56 информацию, но никогда не начнет ее бесполезное редактирование. Как только пользователь 1 ушел с накладной 56, в таблице LOCKER исчезла эта строка("1 INVOICE 56") и накладная свободна для других пользователей. Вот в моменты записи/чтения в таблицу LOCKER транзакции просто доктор прописал — эти моменты столь кратковременны, что пессимистичная блокировка не видна для пользователей.
Иначе — бесконечные непонятки между пользователями.
[безжалостно skipped]
AK>Что pessimistic, что optimistic — такая реализация одновременного доступа только лишь с помощью транзакций не позволяет "спокойно" работать с такой простейшей базой данных, которая приведена в моем примере. У нас в сети всего три (очень редко четыре) компьютера, и между ними иногда происходят конфликты, связанные с одновременным доступом. Правильно, или ты ждешь неизвестно сколько, пока запись не освободится, или ты получаешь откат после вдумчивого редактирования накладной с пояснением, что ты не имеешь, оказывается, право эту накладную редактировать.
AK>Пришлось искать какой-то выход из положения. Ничего лучшего не придумав, в базу данных пришлось ввести служебную таблицу (назовем ее условно LOCKER), которая содержит в себе все имеющиеся на данный момент блокировки. Она выглядит примерно так:
AK>User Table Info(номер блокированного документа) AK>================================================================= AK>1 INVOICE 56 AK>1 ORDER 12 AK>2 INVOICE 55 AK>3 INVOICE 57
AK>итак, пользователь 1 зашел в накладную 56. При этом он может редактировать эту накладную, либо пить кофе в другой комнате (что тоже иногда встречается). Пользователь N, заходя в накладную 56, получает информацию из таблицы LOCKER, что накладная 56 заблокирована пользователем 1. Он может читать из накладной 56 информацию, но никогда не начнет ее бесполезное редактирование. Как только пользователь 1 ушел с накладной 56, в таблице LOCKER исчезла эта строка("1 INVOICE 56") и накладная свободна для других пользователей. Вот в моменты записи/чтения в таблицу LOCKER транзакции просто доктор прописал — эти моменты столь кратковременны, что пессимистичная блокировка не видна для пользователей.
AK>Иначе — бесконечные непонятки между пользователями.
Все правильно! Таким образом, вы реализовали чистейшей воды Pessimistic Locking. Таблица LOCKER используется как менеджер локов.
Недостатоки такого подхода:
— все приложения обязаны быть "вежливыми" и не забывать посмотреть в эту таблицу.
— если пользователь заблокировал накладную, пошел пить кофе, отравился и умер, то накладная останется заблокированной навсегда.
Достоинтство: Легким движением руки можно добавить возможность административного вмешательства. Например, менеджер или там администратор может "сломать" замок, поставленный нерадивым пользователем.
Теперь о том, как все это можно было бы сделать поверх базы данных, которая поддерживает pessimistic locking:
0. Мы отключаем ожидание разблокирования по умолчанию
1. Когда мы открываем накладную, мы ставим на нее shared lock (в случае неудачи сразу сообщаем пользователю, что прямо сейчас кто-то пишет)
2. Когда пользователь пытается начать редактирование, мы переводим shared lock в update lock. Если нам это не удается, значит кто-то уже начал редактирование.
3. Теперь полоьзователь долго и вдумчиво редактирует накладную. Все могут спокойно читать, но пункт 2 никто из них не пройдет.
4. Наконец, пользователь давит "сохранить". В этот момент мы пытаемся получить exclusive lock, и нам придется подожлать, пока все дочитают. Но нам точно известно, что именно мы получим возможность записать данные, а не кто-то другой.
5. Все, запись удалась, можно жить дальше.
Возможная модификация: для чтения мы получаем shared lock и сразу же его отпускаем, чтобы не создавать другим задержек на шаге 4. При выполнении шага 2 мы перечитываем данные, чтобы учесть возможные изменения, произошедшие между 1 и 2.
Преимущество такого подхода в том, что мы защищены от негодяев средствами сервера. Во-первых, он не даст нарушить блокировку никому другому, даже если он ничего не знает про наши соглашения. Во-вторых, если клиентская программа упала, то все блокировки будут автоматически отпущены.
Как реализовать подобное поведение средствами MS SQL Server я знаю — нужно всего лишь покопаться в настройках lock timeout, и применять некоторое шаманство с set transaction isolation level или хинтами в select-ах. Насчет других серверов пришлось бы покопать доки пару дней.
Если интересны подробности реалтзации такого щастья для MSSQL — могу написать. Кстати, можно даже отловить, кто именно нас заблокировал (в смысле идентификатор пользователя), и, если применяется WinNT Autentification, то послать ему мессагу через Messenger Service.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
...
S>Как реализовать подобное поведение средствами MS SQL Server я знаю — нужно всего лишь покопаться в настройках lock timeout, и применять некоторое шаманство с set transaction isolation level или хинтами в select-ах. Насчет других серверов пришлось бы покопать доки пару дней.
S>Если интересны подробности реалтзации такого щастья для MSSQL — могу написать. Кстати, можно даже отловить, кто именно нас заблокировал (в смысле идентификатор пользователя), и, если применяется WinNT Autentification, то послать ему мессагу через Messenger Service.
Что использую: MS SQL 2005 Express + Delphi DBE
Что делаю: прогу которая пользует базу заведенную в этом самом MSSQL в многопользовательском режиме (с базой будут работать только при помощи моей проги).
Губокого знания транзакций, тригеров и прочей святотени серверов БД не имею, писал раньше в основном однопользовательские проги...
Что Хочется:
1) если один пользователь уже работает с записью, т.е. не просто смотрит, а именно меняет ее, то чтобы другой пользователь при открытии данной записи мог узнать, что над этой записью уже кто-то корпит (и желательно узнать кто именно, один или несколько — зная кто корпит можно узнать за какие именно поля он отвечает)
2) если за время работы пользователя над записью, кто-то ее по тихому поменял, то в моментнепосредственно внесенния изменений пользователь должен знать о том, что запись поменяли (желательно знать кто именно, один или несколько, но не обязательно)
У меня проблема следующего рода:
при одновременной работе нескольких экземпляров программ — они могут редактировать одну и туже запись даже не зная об этом — никаких ошибок при этом не возникает. — отсюда я сделал вывод что имеем дело с вариантом optimistic.
как я не пытался, так и не смог найти как же перейти в режим pessimistic ни в настройках сервака и базы, ни в свойствах компонент — нет ничего подобного (напомню, используется BDE, а не ADO). В ADO нашел свойство LockType у компонента TADOTable, выставил в pessimistic, но после открытия таблицы LockType сам переходит в состояние BatchOptimistic, на этом мое знакомство с ADO пока закончилось... Далее с BDE...
В BDE дошел до использования его внутренних функции:
DbiIsRecordLocked — при помощи этой функции можно проверить блокировку записи
DbiGetRecord — выставить записи WRITELOCK
DbiRelRecordLock — снять LOCK
DbiOpenLockList — открыть список всех блокировок
дык вот, перед тем как начать изменять запись пытаюсь проверить нет ли блокировки (DbiIsRecordLocked) — говорит нету, проверяю какие у нас имеются блокировочки(DbiOpenLockList) — никаких нема, ну нету и хорошо(смотрю в мониторе сервака-действительно нету), после того как вошел в режим записи опять проверяю нет ли блокировки (DbiIsRecordLocked) — говорит есть, проверяю какие у нас имеются блокировочки(DbiOpenLockList) — смотрю действительно есть одна, ну хорошо думаю, лезу в монитор сервака- как не было, так и нету блокировок((, ну и соответственно после Cancel и после Post проверяю блокировки и если есть снимаю...
вот такая грустная история...
Подытожим:
Стоит ли перейти с BDE на ADO, чем он лучше???
Как и где можно выставить Lock режим (pessimistic,optimistic)???
Как узнать редактирует кто-либо (и кто именно) сейчас запись или нет (что нужно доработать и как это лучше сделать)???
Как узнать была ли изменена запись с того момента как юзверь начал ее тиранить и если да, то кем (что нужно доработать и как это лучше сделать)???
Буду очень благодарен, если поможете...
ну а пока буду сам искать-ковырять
Здравствуйте, MASReady, Вы писали: MAS>Подытожим: MAS>Стоит ли перейти с BDE на ADO, чем он лучше???
Не имеет значения. Управление блокировками все равно придется делать вручную. MAS>Как и где можно выставить Lock режим (pessimistic,optimistic)???
При работе на уровне датасетов вся блокировка оптимистическая, хоть и некорректная. MAS>Как узнать редактирует кто-либо (и кто именно) сейчас запись или нет (что нужно доработать и как это лучше сделать)???
Нужно сделать все вручную:
— перед началом редактирования вызвать sp_get_app_lock, придумав достаточно уникальный идентификатор записи
— если вернулось значение, говорящее об истечении таймаута, можно подсмотреть во view sys.dm_tran_locks идентификатор виновной сессии и узнать через sys.sysprocesses кто ее инициировал.
MAS>Как узнать была ли изменена запись с того момента как юзверь начал ее тиранить
Для этого к таблице нужно добавить поле типа timestamp. Оно всегда меняется при изменении записи. MAS>и если да, то кем (что нужно доработать и как это лучше сделать)???
Нет, этого сделать нельзя. Доработать можно при помощи триггера, который запишет в нужное место значение DATABASE_PRINCIPAL_ID()
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Значит, так. Вышеобсужденная кислотность (ACIDity) может достигаться различными способами. В основном различают два: pessimistic locking и optimistic locking.
А скажите, пожалуйста, виды блокировок — это свойство сервера, соединения, транзакции, системы или ещё чего?
Здравствуйте, individual, Вы писали: I>А скажите, пожалуйста, виды блокировок — это свойство сервера, соединения, транзакции, системы или ещё чего?
Свойство блокировок.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
I>>А скажите, пожалуйста, виды блокировок — это свойство сервера, соединения, транзакции, системы или ещё чего? S>Свойство блокировок.
Я хотел узнать следующее. В клиентском приложении происходят события типа connect, begin transaction, отправка SQL-запроса, disconnect. В какой момент я определяю, какая у меня будет блокировка и как?
I>>>А скажите, пожалуйста, виды блокировок — это свойство сервера, соединения, транзакции, системы или ещё чего? S>>Свойство блокировок.
I>Я хотел узнать следующее. В клиентском приложении происходят события типа connect, begin transaction, отправка SQL-запроса, disconnect. В какой момент я определяю, какая у меня будет блокировка и как?
При неявном использовании блокировок
блокировками управляет сама транзакция
IMHO этот подход предпочтительнее...
В MSSQL есть 2 способа:
1) Перед началом транзакции через
SET TRANSACTION ISOLATION LEVEL ...
2) В самой транзакции для конкретного оператора можно указать
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, individual, Вы писали: I>>А скажите, пожалуйста, виды блокировок — это свойство сервера, соединения, транзакции, системы или ещё чего? S>Свойство блокировок.
Смотря что понимается под словом "виды"
Если говорить о методе реализации (Какой ресурс блокирует и когда)
то это свойство сервера