Есть ли способ заблокировать запись в базе данных Access - PullRequest
0 голосов
/ 26 марта 2019

Мне нужно найти способ получить уникальную «Проверку» из базы данных MS Access в многопользовательской среде.Вот мой пример таблицы:

enter image description here

Проверка поля уже заполнена и никогда не будет изменяться, mID и getDate добавляются / удаляются пользователем (используя VBAscript).
Правило для сценария VBA:
1. Найдите первую свободную строку mID,
2. Заполните ее текущим именем пользователя и текущей датой,
3. Верните соответствующее поле проверки

Кажется, что это легко сделать, вот код, который я разработал:

Function access() As String

    Dim con As ADODB.Connection
    Dim Records As ADODB.Recordset
    Dim record As ADODB.record

    Set con = New ADODB.Connection
    Set Records = New ADODB.Recordset
    Set record = New record

    con.ConnectionString = sDBPath
    con.Open

    With Records
        .ActiveConnection = con
        .Source = "tblVerificationNr"
        .LockType = adLockOptimistic
        .CursorType = adOpenDynamic
        .Open

    Do Until .EOF
        If IsNull(.Fields("mID")) Then
            access = .Fields(1)
            .Fields("mID") = "asdf"
            .Fields("getDate") = Now
            .Update
            Exit Do
        End If
        .MoveNext
    Loop

    End With

End Function

Код работает хорошо для 1 пользователя, но когда несколько пользователей начинают запрашивать его (почти) одновременно, тогда ониполучить тот же номер подтверждения.(Если пользователь2 отправит запрос на 0,1 сек позже, чем пользователь1, то он найдет ту же строку - Verification = 3006. В результате первый пользователь1 введет свой mID, а getDate AND получит подтверждение = 3006, но спустя 0,1 сек. User2перезапишет эти данные и получит тот же проверочный номер).

Каким будет обходной путь для этого?Как обеспечить уникальность проверки?Возможно ли заблокировать найденную запись пользователем user1, чтобы user2 не смог найти эту запись?

Пробовал также с помощью операторов SQL:

sSelectSQL = "SELECT TOP 1 tblVerificationNr.VerificationNumber, tblVerificationNr.Mid, tblVerificationNr.getDate FROM tblVerificationNr WHERE (((tblVerificationNr.[mID]) = '" & UserName() & "')) ORDER BY tblVerificationNr.getDate DESC, tblVerificationNr.ID"
sUpdateSQL = "UPDATE (SELECT TOP 1 tblVerificationNr.VerificationNumber, tblVerificationNr.Mid, tblVerificationNr.getDate FROM tblVerificationNr WHERE (((IsNull([tblVerificationNr].[mID]))<>False)) ORDER BY tblVerificationNr.VerificationNumber)  AS a SET a.mID = '" & UserName() & "', getDate = '" & Now() & "'"

и та же проблемаздесь.

1 Ответ

1 голос
/ 26 марта 2019

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

.Source = "SELECT TOP 1 * FROM tblVerificationNr WHERE mID IS NULL ORDER BY ID;"

Сортировка по VerificationNumber, если вы предпочитаете, но, вероятно, убедитесь, что поле сортировки проиндексировано в таблице.

Тогда не зацикливайтесь, просто установите значения полей:

If Not .EOF Then
    .Fields("mID") = "asdf"
    .Fields("getDate") = Now
    .Update
    access = .Fields(1)
End If
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...