【问题标题】:Ms Access lock table while inserting dataMs 插入数据时访问锁表
【发布时间】:2014-10-31 19:40:48
【问题描述】:

在 Access 2003 数据库中,我有一个“Inscriptions”(订阅)数据库,主键位于 idPersonnel(员工)和 idSession 两个字段上。 我制作了一个表单,以便用户可以选择一个会话(在列表框中),然后选择一个或多个员工(另一个列表框)并使用一个按钮将他们订阅到该会话,在 VBA 端,首先检查是否有足够的session 上的房间(由“Sessions”表上的“MaxParticipants”字段定义,链接到 idSession 上的“Inscriptions”表),然后在“Inscriptions”表中插入数据

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

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

但在 MS Access 中似乎不可能。 MS Access 中防止会话的参与者超过最大数量的可能性是什么?任何帮助表示赞赏。

【问题讨论】:

  • “在 MS Access 中似乎不可能” - 实际上,在 Access 2010 及更高版本中,使用插入数据前宏是可能的(很简单,真的) .但是,如果您无法使用过时的版本(您知道微软在六个月前停止支持 Office 2003,对吗?),那么您的选择就会更加有限。
  • 感谢您的回复。在所有用户都迁移到 2010 之前,我一直坚持使用 2003。那么这些有限的选项是什么?

标签: ms-access vba


【解决方案1】:

实现目标的一种方法是在事务中执行 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

【讨论】:

  • 完美运行 :) 感谢您的建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-31
  • 1970-01-01
相关资源
最近更新 更多