ADO Блокировка записи

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

ADO Блокировка записи

Сообщение SergT » 22.09.2006 (Пт) 13:04

Помогите разобраться с блокировками.
Что есть:
Локальная сеть, БД (mdb) находится на сервере. 20 пользователей. VB6.

Вопросы:
1. Необходимо заблокировать в таблице REG только одну запись (Where ID=" & FndID) и удерживать эту блокировку до завершения программы.
Зачем? Чтобы при попытке удалить записи из таблицы REG , удалились только незаблокированные. (В случае обрыва связи с сервером, коннекты
других пользователей тоже должны оборваться и блокировки убраться и, если входит кто-то первым, после возобновления связи с ервером, у него есть
шанс очистить таблицу от "мусора",появившегося в результате аварийного завершения. Или я неправильно полагаю?)

Использую следующую схему:
CN.CursorLocation = adUseClient
CN.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\\Server\Local\ ... \Test.mdb" & ";Persist Security Info=False;Jet OLEDB:Database Password=''"
RG.Open "SELECT * FROM REG Where ID=" & FndID, CN,adOpenDynamic,adLockPessimistic
Но не могу точно понять, работает такое или нет. Блокируется одна запись или вся таблица?

2. Все аналогично, но в другой таблице следует поставить True в поле BLOCK. Это могут делать одновременно 20 пользователей. Кто окажется первым?
Прежде чем поставить True, необходимо убедиться, что его значение False! Но пока проверяю, кто-то может изменить значение. Как грамотнее поступить?

3. Как ведет себя ADO Connect при кратковременном обрыве связи с сервером? Попытаеся ли восстановить соединение? Если да, то какое время допустимо?

Очень надеюсь на Вашу помощь, но прошу ответить, если Вы точно уверены в своем ответе или есть иное решение. Времени на эксперименты у меня почти не осталось.
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Сообщение NashRus » 22.09.2006 (Пт) 13:15

не будет Access блокировать одну запись и уж тем более нельзя удалять "все незаблокированные". порочный подход какой-то.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 22.09.2006 (Пт) 13:18

1. Не пойму, почему нельзя делать DELETE FROM REG WHERE ID <> ...
2. Обычно для этого используют транзакции.
3. Восстанавливать соединение никто не будет. Ну а время таймаута, после которого соединение будет считаться потерянным, ты можешь задавать, когда подключаешься к источнику данных.
Lasciate ogni speranza, voi ch'entrate.

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Сообщение SergT » 22.09.2006 (Пт) 13:31

alibek писал(а):1. Не пойму, почему нельзя делать DELETE FROM REG WHERE ID <> ...


Можно, но следует удалить только мусор, т.е. те записи, которые в данный момент не блокированы другими user-ами. Таким образом можно узнать, кто именно работает с программой Now.

alibek писал(а):2. Обычно для этого используют транзакции.


Вот я их и использую, но впервые. Значит ли использование транзакции, что запустив BeginTransaction, я встаю в очередь и, как только очередь подошла, ни кто мне не мешает работать с записями?[/quote]

alibek писал(а):3. Восстанавливать соединение никто не будет. Ну а время таймаута, после которого соединение будет считаться потерянным, ты можешь задавать, когда подключаешься к источнику данных.

Про это я не слышал. Можно пояснить или ссылку дать?
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Сообщение SergT » 22.09.2006 (Пт) 13:39

NashRus писал(а):не будет Access блокировать одну запись и уж тем более нельзя удалять "все незаблокированные". порочный подход какой-то.

В Access есть понятие "Блокировка изменяемой записи"
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 22.09.2006 (Пт) 13:47

SergT писал(а):Таким образом можно узнать, кто именно работает с программой Now.


Можно так-же содержимое ldb-файла смотреть...

Но, IMHO лучше заходить с другого конца и узнавать кто из пользователей открыл файл базы. Безо всяких блокировок записей в таблице.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Сообщение NashRus » 22.09.2006 (Пт) 13:50

В Access есть понятие "Блокировка изменяемой записи"


и что оно значит? наверное не то что запись редактируется в клиентском рекордсете и она заблокирована при этом ?

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Сообщение SergT » 22.09.2006 (Пт) 13:54

Andrey Fedorov писал(а):Можно так-же содержимое ldb-файла смотреть...
Но, IMHO лучше заходить с другого конца и узнавать кто из пользователей открыл файл базы. Безо всяких блокировок записей в таблице.

Пробовал, но содержимое файла ldb странное... Свою запись читаю, а чужие все из квадратиков :( . Хотя вариант через ldb мне симпатичен.
Правда, при обрыве связи - ldb не исчезает!
Однако, блокировка конкретной записи возможна или нет? И как?

про ldb только что нашел
http://bbs.vbstreets.ru/viewtopic.php?t ... 36fe619a38
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 22.09.2006 (Пт) 14:08

У меня есть определенные сомнения, что возможно заблокировать запись серверного курсора (саму таблицу).
Может перейдешь на MSDE?
Lasciate ogni speranza, voi ch'entrate.

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Сообщение SergT » 22.09.2006 (Пт) 14:40

To Alibek:Нет, только VB и Access. Времени нет на другое.
Однако, что по поводу Тразакций и TimeOut? Если нет возможности блокировать, может сосредоточиться на других возможностях?
CN.BeginTrans
...
CN.CommitTrans
Что могут другие пользователи между этими процессами,запущенными моей программой, если так же пользуются BeginTrans и CommitTrans и стучатся в те же таблицы?
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 22.09.2006 (Пт) 14:48

Я бы не рассчитывал слишком сильно на транзакции в Access.
Lasciate ogni speranza, voi ch'entrate.

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Сообщение SergT » 22.09.2006 (Пт) 15:17

alibek писал(а):Я бы не рассчитывал слишком сильно на транзакции в Access.

Тогда надеюсь на совет.
На сервере лежит БД. В разное время 20 пользователей подключаются к ней и работают. БД 200-300 Мб. Необходимо отслеживать все изменения в реальном времени для каждого подключенного пользователя. Плюс - основные данные выводятся в виде дерева VS7. Как отслеживать изменения я, в принципе, решил.
Но вот вносить изменения :( Тут существует опасность при одновременном доступе. Так вот каким путем пошел бы Alibek,
используя только VB6 + любые библиотеки и контролы? Таблицы Access.
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Сообщение NashRus » 22.09.2006 (Пт) 15:21

1. Тут видимо надо логику поведения поменять. Видимо имеет место смесь требуемой бизнес-логики со служебными операциями движка БД. Т.е. мухи отдельно, мясо отдельно.

2. при определенных условиях, при попытке обновить данные (oRs.Update), уже измененные другим пользователем, должно вылезти исключение. это легко смоделировать и проверить.

3. Скорее всего никаких сообщений / ошибок НЕ возникнет.

Код: Выделить всё
Private WithEvents mo_Conn As ADODB.Connection

Private Sub mo_Conn_Disconnect(adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
    '
End Sub

Private Sub mo_Conn_InfoMessage(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pConnection As ADODB.Connection)
    '
End Sub


Надо отлавливать этот момент по исключительной ситуации при операциях с базой и, соответственно, реагировать. Проще всего пользователю сообщить о необходимости переподключиться и переоткрыть все что надо, но, если рекордсеты отсоединенные, то можно выполнить только переподключение.

Хотя конечно 3 вопрос не об этом :) но тем не менее..

Скорее всего, JET провайдер и лезет в базу только при необходимости выполнения операции и только так можно отловить момент отвала коннекта.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 22.09.2006 (Пт) 15:22

Если перечень операций, выполняемых пользователями, не слишком обширный, я бы писал сервер приложений.
Если список операций слишком большой, то я бы перешел на MSDE.
Еще Sebas много вкусного про Remote рассказывал, но навряд-ли у тебя есть возможность переводить весь проект на новую платформу.
Lasciate ogni speranza, voi ch'entrate.

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Сообщение NashRus » 22.09.2006 (Пт) 15:33

и еще. ты вот так вот делаешь

Код: Выделить всё
CN.CursorLocation = adUseClient
CN.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=\\Server\Local\ ... \Test.mdb" & ";Persist Security Info=False;Jet OLEDB:Database Password=''"
RG.Open "SELECT * FROM REG Where ID=" & FndID, CN,adOpenDynamic,adLockPessimistic


а посмотри чему у тебя это равно после открытия рекордсета

Код: Выделить всё
Debug.Print Rg.CursorType, Rg.LockType

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Сообщение SergT » 22.09.2006 (Пт) 15:41

NashRus писал(а):2. при определенных условиях, при попытке обновить данные (oRs.Update), уже измененные другим пользователем, должно вылезти исключение. это легко смоделировать и проверить.

Одну и туже запись менять ( по очереди) не запрещено. Представь себе библиотеку. Один Библиотекарь собирает заказ на книги, в это время они блокируются для других библиотекарей. Создал заказ - закрепил накладную- разрешил собирать заказ по этим книгам, если они остались, другим. В это же время прочие библиотекари действуют аналогично. Т.е таблицы доступны всегда для всех.
Далее, по таймеру, просматриваю изменения и(при наличии таковых) вношу их в дерево (если новые- добавляю, измененные- меняю).
В дереве порядка 30 000 наименований, по этому обновлять его по таблице - не красиво. Тем более, что Библиотекарь не должен отвлекаться от работы с заказом.

to Alibek:
Я читал много Ваших статей, смотрел пример Клиент-Сервер. Но, полагаю, что Сервер должен быть запущен на постоянно включенном компе. Тут ситуация другая. Пользователи включаются, отключаются, подключаются с других компов. Ограничено только их одновременное кол-во. Да еще учесть нестабильную связь с сервером! Библиотеку я привел для примера..
Сервер тоже может вырубаться! Да и запуск программы на самом сервере - проблематичен (по многим причинам).

SQL Server?. Мне пол-года его изучать :( Меня за это время уволят или все же прейдут на 1С, как я не сопротивляюсь.
Последний раз редактировалось SergT 22.09.2006 (Пт) 16:08, всего редактировалось 1 раз.
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Сообщение NashRus » 22.09.2006 (Пт) 16:04

не понял про библиотекарей. хотелось бы, конечно, вникнуть в эту логику, но нет мозговых резервов на это. я отвечал вот на это:

2. Все аналогично, но в другой таблице следует поставить True в поле BLOCK. Это могут делать одновременно 20 пользователей. Кто окажется первым?
Прежде чем поставить True, необходимо убедиться, что его значение False! Но пока проверяю, кто-то может изменить значение. Как грамотнее поступить?


т.е. открываем рекордсет где заведомо BLOCK = FALSE, надо поставить TRUE - мы и ставим и пытаемся сохраниться, НО! если уже кто-то поставил и сохранил TRUE, то при oRs.Update - возникнет exception. Вроде куда уж грамотнее ?

SergT
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 237
Зарегистрирован: 22.06.2005 (Ср) 21:50
Откуда: Москва

Сообщение SergT » 22.09.2006 (Пт) 16:16

TO NashRus:
Прости, я сразу не понял. Сейчас попробую, но сдается мне, что логично кратковременно блокировать таблицу,проверить,поставить,разблокировать. И еще надо про транзакции почитать. Блин, как оно...
Может есть у кого примерчик одновременной работы пользователей с одной таблицей? У меня уже голова кругом :roll:
Л. Толстой, «зачем обдумывать обдуманное, бери готовое и иди дальше, в этом сила человечества»
"Всё в наших руках, поэтому их нельзя опускать" (Коко Шанель)

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Сообщение NashRus » 22.09.2006 (Пт) 16:22

ты бы не парился. сделал бы пилотную версию - юзера сами придут с вопросами или сам за этим понаблюдай. в любом случае:
- Access
- 20 пользователей
- 200-300 мегов

вопросы просто обеспечены :roll:

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 22.09.2006 (Пт) 19:40

Access прекрасно блокирует запись, если начать её редактирование при серверном курсоре и пессимистичной блокировке.

Селектишь нужную запись с adUseServer, adOpenDynamic и adLockPessimistic. Изменяешь значение любого поля на что угодно (rs.Fields("LockField").Value = 0). Если не возникло исключения, блокировка у тебя.
Если возникло, соответственно.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Сообщение NashRus » 22.09.2006 (Пт) 23:45

Access прекрасно блокирует запись

не понял. из каких умозаключений это следует ? может страницу ? а может таблицу ?

а насчет серверного курсора это точно. автор получает рекордсет не с теми параметрами открытия, которые рассчитывает получить судя по параметрам открытия.

в случае с Jet выбор курсора серверного или клиентского - вопрос функциональности, потому как все равно нагрузка на клиенте - эквивалент клиентского курсора.

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 23.09.2006 (Сб) 2:02

NashRus писал(а):не понял. из каких умозаключений это следует ?

Из мануала по ADO.

NashRus писал(а): может страницу ? а может таблицу ?

Нет, запись.

NashRus писал(а):в случае с Jet выбор курсора серверного или клиентского - вопрос функциональности, потому как все равно нагрузка на клиенте - эквивалент клиентского курсора.

В общем случае, для общей функциональности - это правда не такой важный вопрос.
В случае же, когда требуется блокировка записи, то это только серверный курсор, и только пессимистичная блокировка.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Mail.ru [бот], SemrushBot и гости: 134

    TopList