单个用户数据库中出现“写冲突”错误

时间:2013-05-14 17:41:45

标签: sql-server ms-access access-vba

在Citrix下针对SQL Server 2008R2后端运行MS Access 2010前端。

我有一张表已经工作了很长时间。一个按钮后面的代码突然开始产生“写冲突”错误。它发生在几天前,经过几个小时倾倒未更改的代码(通过在线文本比较工具确认),并让另一位程序员在这里查看它,我唯一的解决方案是抓住前端的生产版本并开始重新应用我的更改。

它已经运行了2天,现在又出现了错误。我正在改变代码,但是以不同的形式。我需要完成此表单上的流程以测试其他表单。

以下是生成写冲突的代码:

Private Sub btnStart_Click()

Dim AuditID As String
Dim UserStatus As String
Dim SubmitPeerRev As Boolean
Dim PRPercent As Single
Dim ExaminerAudits As Integer
Dim ReviewAudits As Integer
Dim rs As DAO.Recordset
Dim UserName As String
Dim SQLString As String

    On Error GoTo Error_Handler

    UserStatus = funUserLookup("Status", Raw:=True)
    'get the percentage/whole number
    'this is the percentage that should be submitted for review
    If IsNull(DLookup("ItemValue", "tblConfig", "Item = '" & UserStatus & "'")) Then
        Form_frmMenu.MsgBoxTimed ("Your user ID is not configured correctly within the     AP_Audit DB." & vbCrLf & _
            "You cannot start an audit." & vbCrLf & _
            "Please contact your manager to get it set correctly.")
        Exit Sub
    Else
        PRPercent = CSng(DLookup("ItemValue", "tblConfig", "Item = '" & UserStatus & "'"))
    End If
    UserName = funUserLookup("Examiner")

    'get total audits done
    SQLString = "SELECT count(*) as A " & _
                "  FROM tblAuditAtt " & _
                " WHERE Examiner = '" & UserName & "'" & _
                "   AND month(aMonth) = " & Month(Now()) & _
                "   AND year(aMonth) = " & Year(Now())
    Set rs = CurrentDb.OpenRecordset(SQLString, dbOpenDynaset)
    ExaminerAudits = rs.Fields("[A]")

    'get peer-reviewed audits done
    SQLString = "SELECT count(*) as A " & _
                    "  FROM tblAuditAtt " & _
                    " WHERE TraineeExaminer = '" & UserName & "'" & _
                    "   AND Month(aMonth) = " & Month(Now()) & _
                    "   AND Year(aMonth) = " & Year(Now())
    Set rs = CurrentDb.OpenRecordset(SQLString, dbOpenDynaset)
    ReviewAudits = rs.Fields("[A]")
    Set rs = Nothing

    If DLookup("Started", "tblAuditAtt", "AttAudit_ID = " & Me.AttAudit_ID) Then
        Form_frmMenu.MsgBoxTimed "This audit was already started by someone else. Select a new one."
        Me.Requery
        Exit Sub
    End If
        'UserName = funUserLookup("Examiner")
        If ReviewAudits = 0 Then            'ensure 1 review - prevents divide by 0
            Me.TraineeExaminer = UserName
            Me.TraineeExaminer.Visible = True
            Me.TraineeExaminer.Top = 2280
            Me.Examiner.Visible = False
        ElseIf ExaminerAudits = 0 And PRPercent < 1 Then      'ensure 1 non-review if < 100% peer-review
            Me.Examiner = UserName
            Me.TraineeExaminer.Visible = False
            Me.Examiner.Visible = True
        ElseIf ExaminerAudits / (ExaminerAudits + ReviewAudits) > 0.99999999 - PRPercent Then
            'the tiny fraction is needed because 0 > 0 = false & 100% trainees would get a straight submit
            Me.TraineeExaminer = UserName
            Me.TraineeExaminer.Visible = True
            Me.TraineeExaminer.Top = 2280
            Me.Examiner.Visible = False
        Else
            Me.Examiner = UserName
            Me.TraineeExaminer.Visible = False
            Me.Examiner.Visible = True
        End If

    Me.StartDate = Format(Form_frmMenu.GetSQLTime, "mm/dd/yyyy")
    Me.Started = True
    Me.Dirty = False
    Form_frmMenu.ExecSP "AUDIT_AttAuditStart", 120, False, "@AuditID", adInteger, Me.AttAudit_ID
    'this is failing, for reasons yet unknown, so only continue if it hasn't
    If Nz(DLookup("AttAudit_A", "tblAuditAtt_A", "AttAudit_ID = " & Me.AttAudit_ID), 0) > 0 Then
        Me.btnStartEnd.Enabled = True
        Me.btnStartEnd.SetFocus
        Me.btnStart.Enabled = False
        Me.frmAttAudit_A_Sub.Requery
        SetSubFormView  'now that we know what type of audit & have questions, set up the proper view
    Else
        Me.TraineeExaminer = ""
        Me.Examiner = ""
        Me.StartDate = ""
        Me.Started = False
        Me.Dirty = False
        SQLString = Form_frmMenu.LogError(0, "Audit did not start properly", "User Defined", "frmAttAudit_A.btnStart_Click", "Stored procedure failed to insert records")
    End If

    Exit Sub

Error_Handler:
    If Form_frmMenu.LogError(err.Number, err.Description, err.Source, "frmAttAudit_A.btnStart_Click", SQLString) = "Next" Then
        Resume Next
    Else
            Resume
        End If

    End Sub

注意:

  • 我在我们的开发服务器上运行它,我是唯一使用它们的人 表格
  • 我添加了一个时间戳列,但似乎没有 差
  • 我在每个绑定表单字段更改后移动me.dirty = false代码,这无效
  • 以前唯一的解决方案是获取生产代码并手动重新应用我的所有更改。
  • 你可以看到另一个奇怪的原因导致插入查询失败。我不知道自从更改为调用存储过程后是否发生了,但是当有docmd.runsql语句时它失败了
  • 我在另一篇文章中收到了一条禁止在Citrix环境中挂钩的建议,因为这可能会让事情变得更糟,但我们的IT人员不会考虑这一点。

关于如何解决此问题的任何其他想法或建议?当Access决定呕吐时,我真的没有时间每隔几天重做一次我的工作。

1 个答案:

答案 0 :(得分:0)

如果底层sql server表具有空值的位字段,则在通过odbc链接到sql server时,这可能会导致访问写冲突错误。它与访问权限有关,首先将空位值转换为0,然后尝试应用您所做的更改并导致写入冲突。

就我而言,我通过将新的位字段默认为0并在现有字段中将空值替换为0来解决它。