插入数据时Ms Ms锁定表

时间:2014-10-31 09:44:10

标签: ms-access access-vba

在Access 2003数据库中,我有一个“Inscriptions”(订阅)数据库,其中包含2个字段idPersonnel(employee)和idSession的主键。 我创建了一个表单,以便用户可以选择一个会话(在列表框中),然后选择一个或多个员工(另一个列表框)并使用一个按钮将它们挂到该会话中,在VBA端,首先检查是否有足够的会议室(由“会话”表上的“MaxParticipants”字段定义,链接到idSession上的“铭文”表),然后在“铭文”表中插入数据

这在单用户环境中工作正常,但如果2个人想同时在同一会话中加入某些员工,则会失败,因为我在检查和插入之间有确认消息。因此,2个用户可以选择员工,获取确认消息(此时两者都被告知有足够的空间),导致有更多的人加入会话。 幸运的是,如果两个用户都试图将相同的员工插入到该表中,则会出现重复错误,但如果员工不同,则会进行插入。

在另一个数据库引擎上,比如SQL服务器,我会使用一个存储过程来锁定表,执行检查和插入然后解锁表。

但在MS Access中似乎不可能。 MS Access有哪些可能阻止会话超过最大参与者数量?任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:2)

实现目标的一种方法是在事务中执行INSERT,计算该会话的参与者,并在新的总数超过限制时回滚事务:

Option Compare Database
Option Explicit

Sub AddParticipant()
    Dim cdb As DAO.Database, cws As DAO.Workspace, _
            qdf As DAO.QueryDef, rst As DAO.Recordset

    ' test data
    Const idPersonnelToAdd = 4
    Const idSessionToAdd = 2

    Set cdb = CurrentDb
    Set cws = DBEngine.Workspaces(0)
    cws.BeginTrans
    Set qdf = cdb.CreateQueryDef("", _
            "PARAMETERS prmIdPersonnel Long, prmIdSession Long; " & _
            "INSERT INTO Inscriptions (idPersonnel, idSession) " & _
            "VALUES (prmIdPersonnel, prmIdSession)")
    qdf!prmIdPersonnel = idPersonnelToAdd
    qdf!prmIdSession = idSessionToAdd
    qdf.Execute dbFailOnError
    Set qdf = Nothing
    Set qdf = cdb.CreateQueryDef("", _
            "PARAMETERS prmIdSession Long; " & _
            "SELECT " & _
                "Count(*) AS NumParticipants, " & _
                "First(MaxParticipants) AS Limit " & _
            "FROM Inscriptions INNER JOIN Sessions " & _
                "ON Inscriptions.idSession = Sessions.idSession " & _
            "WHERE Sessions.idSession = prmIdSession")
    qdf!prmIdSession = idSessionToAdd
    Set rst = qdf.OpenRecordset(dbOpenSnapshot)
    If rst!NumParticipants <= rst!Limit Then
        cws.CommitTrans
        Debug.Print "INSERT committed"
    Else
        cws.Rollback
        Debug.Print "INSERT rolled back"
    End If
    rst.Close
    Set rst = Nothing
    Set qdf = Nothing
    Set cws = Nothing
    Set cdb = Nothing
End Sub