伺服器上的後端不斷進入不一致的狀態
我建立了一個Access數據庫。它最初是為 6 人準備的,但我看到它最多 20 人,所以這可能是問題所在。無論如何,後端一天會出現幾次不一致的狀態。通常可以通過打開後端來解決這個問題,它提供恢復它並且通常這樣做。
回答評論中的一個問題:發生的情況是前端不再能夠讀取後端中的任何表,因此引發錯誤。
當我打開後端時,狀態如下:
Microsoft Access 檢測到此數據庫處於不一致狀態,並將嘗試恢復該數據庫。在此過程中,將製作數據庫的備份副本,並將所有恢復的對象放入新數據庫中。然後 Access 將打開新數據庫。未成功恢復的對象名稱將記錄在“恢復錯誤”表中。
唯一的選擇是按“確定”。通常,這可以在原地完成,但是當我在 VPN 上查看文件時,有時會發現它旋轉了一會兒。在這種情況下,我可以將不一致的文件複製到我的硬碟驅動器,打開它,按 OK,然後讓它完成它的工作。它通常只需要幾秒鐘。那時它說:
Microsoft Access 已恢復此數據庫。檢查數據庫以確認沒有失去的數據庫對象。
到目前為止,除了一次我不得不去一個稍舊的備份之外,這已經成功了。
數據庫不是特別複雜(我不認為),但它確實有一些 VBA。
數據庫的基本思想是我們正在跟踪需要通過一組流程但被分解的批次。所以我們可能會收到 1000 個項目,然後讓其中 300 個進入預篩選,然後再有 100 個,依此類推,經過大約 8 個步驟。
我這樣做的方式(我很樂意改變 - 我只是不知道要改變什麼)是有一個小的送出表,它跟踪進入的批次,以及一個更大的表(稱為原因無關緊要的預購),它跟踪訂單項。
預購表有相當多的欄位(大約 75 個)。但對此重要的是數量欄位和狀態欄位。狀態欄位在整個過程中跟踪項目(因此從步驟 1 = 接收到 8 = 發貨或其他)。數量跟踪此批次中有多少此特定項目以及處於此狀態的其他屬性。
然後,這些步驟中的每一個都有表單,後面有非常相似的 VBA。其中一個欄位基本上是“移動到下一步的數量”(這是預購表中最初預設為 0 的欄位之一)。使用者填寫此數量(可能還有一些附加資訊)並按下按鈕來處理該步驟。
VBA:
- 為預購表打開一個記錄集 (rs),其中狀態為 1(比如說),並且要進行下一步的數量大於 0。
- 它還打開預排序表 (rs2) 的 appendonly 記錄集。
- 然後它遍歷 rs 中的記錄,向下調整數量,並附加一個新的記錄副本,其中包含新的數量和更新的狀態。
以下是其中一個螢幕的範例。其他的也是類似的,儘管有一些細微的差別可能很重要,也可能不重要。
Private Sub btnProcess_Click() DoCmd.Hourglass True Dim db As Database Dim rs As DAO.Recordset Dim rs2 As DAO.Recordset Set db = CurrentDb Set rs = db.OpenRecordset("SELECT * FROM tblPreorder " & _ "WHERE (((tblPreorder.StatusID)=1) AND ((tblPreorder.PSQuantity)>0));", dbOpenDynaset, dbFailOnError) If rs.EOF Then MsgBox "No records found for processing" rs.Close DoCmd.Hourglass False Exit Sub End If Set rs2 = db.OpenRecordset("tblPreorder", dbOpenDynaset, dbAppendOnly) rs.MoveFirst Do Until rs.EOF myQuantity = rs("Quantity").Value PSQuantity = rs("PSQuantity").Value rs2.AddNew For Each fld In rs.Fields SFld = fld.Name 'to catch special fields Select Case SFld 'special cases Case "ID": 'do nothing Case "Quantity": rs.Edit rs(SFld).Value = myQuantity - PSQuantity rs.Update rs2(SFld).Value = PSQuantity Case "Comment": If Len(Trim(rs("PSComment")) > 0) Then rs2(SFld).Value = Trim(rs("Comment")) & vbCrLf & Trim(rs("PSComment")) Else rs2(SFld).Value = rs(SFld) End If Case "StatusID": rs2(SFld).Value = 2 'Changes the status from 1 to 2 Case "DateChanged": rs2(SFld).Value = Now() Case "EmployeeID": rs2(SFld).Value = UserID() Case "Location": If rs("PSLocation") <> "" Then rs2(SFld).Value = rs("PSLocation") End If Case "PSDate": rs2(SFld).Value = Now() Case "PSEmployeeID": rs2(SFld).Value = UserID() Case "PSQuantity": rs.Edit rs(SFld) = 0 rs.Update rs2(SFld) = 0 Case "ReleasedFiles": 'do nothing Case Else: rs2(SFld).Value = fld.Value End Select Next fld rs2.Update rs.MoveNext Loop rs.Close rs2.Close c = Me.CurrentRecord Me.Requery On Error Resume Next: DoCmd.GoToRecord acDataForm, Me.Name, acGoTo, c MsgBox "Items moved to BNC Request" DoCmd.Hourglass False End Sub
我的問題:
- 當然,如果您發現任何明顯錯誤的地方,請告訴我。當它只是我測試它時,它就像一個魅力。我從來沒有設法複製這個問題,但我可以看到它正在生產版本中發生。
- 我已經遵循了幾個網站上關於避免這種情況的建議(例如https://www.techrepublic.com/article/get-it-done-top-10-ways-to-prevent-access-database-corruption/)。我基本上是在修補和嘗試,因為我根本不知道問題是什麼。例如,我在上面的程式碼中從記錄集切換到 DAO.recordset。好像沒什麼區別,所以我可能會回去。每個人都在使用 Access 365,而後端是 Access 365,因此使用 Access 特定的記錄集似乎很有意義。我關閉所有記錄集(rs.close);我編譯VBA;我已將前端保存為acde;所有使用者在自己的電腦上使用acde;所有使用者都使用有線連接;我有版本控制,所以每個人都在使用最新的前端。
- 我想主要問題是:我該如何診斷?我可以很容易地想像放入一個新表來跟踪誰在按下程序按鈕以及何時以及哪一個。我可能會這樣做,看看在導致腐敗的過程中會發生什麼。但是,您對跟踪什麼有什麼建議,是否有任何其他技巧和提示可以解決這個問題?
程式碼特定問題:
- Recordset 或 DAO.Recordset 或其他什麼東西?
- dbFailOnError 或 dbSeeChanges 或其他什麼東西?
- rs.Edit … rs.Update 在我循環時更新的幾個欄位(目前程式碼)?還是在循環的任一側都有一個 rs.Edit … rs.Update?
- 我應該手動保留或阻止人們同時執行類似的程式碼嗎?這樣做有點冒犯了我,因為我有點想像製作 MS Access 的人在這種事情上會比我做得更好。但我可能會在某個地方設置一個標誌,讓人們等待輪到他們。我仍然會擔心比賽條件。
更廣泛的數據庫問題:
- 是否需要調整其他秘密設置以盡量減少此問題?每個人都在使用 MS Access 365。命名自動更正選項、過濾器查找選項、記憶體、數據類型支持選項。我真的不知道這些做什麼,我懷疑到處都有陷阱!我有一個類似的數據庫,多年來一直沒有問題,所以我在這裡陷入了一種錯誤的安全感。
- 我的結構完全錯誤嗎?我可以做一大堆工作——如果能很好地了解它會解決問題,那就太好了!
看起來這是 Access 迄今為止未解決的問題
Microsoft 記錄了以下解決方法:-
點擊 Windows 開始 按 Windows 鍵,然後鍵入命令。右鍵點擊命令提示符並選擇以管理員身份執行。
將以下命令複製並粘貼到命令提示符視窗中:
REG ADD HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters /v DisableLeasing /t REG_DWORD /d 1 /f
網路停止伺服器
網路啟動伺服器
關閉命令提示符視窗。