1

非常に奇妙な(そして不安定な)動作をするかなり大きなAccess DBを継承しました。つまり、データベースへの更新の一部が失われます。これを回避するために何ができるでしょうか?より良いトランザクション制御を提供するためのAccessの設定はありますか?

詳細は次のとおりです。

  • 書き込みアクセス権を持つアクセスユーザーが1人います(非常に限られた数のユーザーによって共有されています。現在、他のユーザーは休暇中なので、私だけです)。
  • 読み取りアクセスしか持たない多くの人が使用する別のアクセスユーザーがいます。
  • データへのいくつかの変更は、書き込みユーザーによって行われます。
  • テーブルやアプリケーションを離れて再入力した後、変更は「コミット」されたようです。
  • しばらくすると(通常は一晩)、変更が失われ、データが古い値に戻ります。

この動作の原因は何ですか?

私たちの理論では、これはAccess内の奇妙なトランザクション制御によって引き起こされます。読み取り専用ユーザーは、クエリまたはフォーム内で使用されるデータに対して、ある種の「排他的ロック」を取得します。ユーザーがそのクエリ/フォームを離れると、Accessはこれがまだデータベースにあることを確認します。その間に書き込みユーザーがデータを変更した場合、読み取り専用ユーザーがクエリ/フォームを離れると、これらの変更は元に戻され、更新が失われます。これは意味がありますか?これはMS-Accessの既知の問題ですか?

また、この問題を回避する方法にも関心があります。これはAccessに固有のものであり、トランザクション制御が優れた「実際の」データベースに切り替えることによってのみ回避できますか?(技術的な観点からは、それは素晴らしいことですが、もちろん、プロジェクトのこの時点では避けたい緊急の作業です。)

ご入力いただきありがとうございます。必要な追加情報がある場合はお知らせください。

4

4 に答える 4

2

ブックマークのバグが見つかってパッチが適用される前に、10年以上前に少し似たようなものを見てきました。その場合、ブックマークナビゲーションを介して編集されたレコードを残すと、エラーをスローせずに編集が失われていました。

その場合、MSがパッチを適用する前の解決策は、レコードから移動する前に保存を強制することでした。

  With Me.RecordsetClone
    .FindFirst "..."
    If Not .NoMatch Then
       If Me.Dirty Then
          Me.Dirty = False
       End If
       Me.Bookmark = .Bookmark
    End If
  End With

もう1つ確認する必要があるのは、エラーレポートがオンになっているかどうか、およびそれがVBEエラー処理設定とどのように相互作用しているかです。生成されたエラーを無視するためにコードにOnErrorResume Nextが散らばっている場合は、コードを完全に書き直す必要があります。それに関する問題は、それが常に期待通りに範囲外になるとは限らないということです。

私はOnErrorResumeNextを使用しません。代わりに、特定のエラーを予期しているがそれを無視したい場合は、そのエラーをトラップして無視します。これにより、予期していなかった他のエラーがメモリホールから消えないようにします。

ここでの私の考えは、ある種のロックの問題が無視されているエラーを生成しているということです。したがって、エラーが報告されることはなく、誰も知らないうちに変更が失われます。

もう1つの注意点は、ドライブが複製されるファイルサーバーにバックエンドが保存されているかどうかです。これは、AccessとJetのセットアップでは不可能です。これは、ファイルイメージが流動的な状態にあるため、Jet/ACEのレコードロックと内部トランザクションがすべて完全に強制終了されるためです。2台のサーバーが複製され、両方のバージョンのMDBが編集されている場所について説明しているレポートを見てきました。その結果、ファイルシステムのレプリケーションが開始され、一方の変更がもう一方の変更で上書きされたときに、データが失われました。

于 2009-07-24T20:22:41.263 に答える
0

いくつかの考え:

  1. 2人が同時に同じテーブルへの書き込みアクセス権を持っている必要が本当にありますか?[ツール]->[オプション]で[レコードのロック]モードと[開く]モードを変更することで、2人目のユーザーを簡単にロックアウトできると思います。

  2. あなたは、更新されたデータは通常、夜に古い自己に戻ると言いました。誰かが同じテーブルを更新する夜間プロセスを実行している可能性がありますか?

于 2009-07-24T18:58:26.347 に答える
0

継承されたMSAccessは常に最高ですよね。明らかな解決策を早期に解決するために、データをSQLServerに移動することをお勧めします。それは本当に大きな仕事ではありません。データベース(GUIとデータ)を別々の.mdbに分割することで、いくつかのメリットが得られる場合もあります。

そうは言っても、私はこれまでそのような行動に出くわしたことがありません。明らかな質問は次のとおりです。

  • データベースの大きさはどれくらいですか?
  • それは何のバージョンですか?
  • 最近圧縮されて修復されましたか(もちろん最初にバックアップを取ります)?

MS Accessで実行できるトランザクション処理がありますが、それはお尻の痛みであり、多くの場合、奇妙なエラーにつながることがわかりました(トランザクションが衝突する方法を模索し始めるまで)。アプリケーションのほとんどはおそらく楽観的ロックを想定しており、デフォルトの動作は、Oracleやその他の実際のデータベースでのトランザクションとは矛盾しています。おそらくそれだけの価値はありません。

もう1つ考えてみましょう。おそらく、書き込みアクセス権を持つ2人が、同じレコードを同時に見ています。1つは、レコードの別のフィールドで更新を行っています。

于 2009-07-24T14:38:41.873 に答える
0

シナリオを明確にしていただければ幸いです。

読み取り専用ユーザーが書き込みユーザーによる変更を失う可能性があるという考えは不可能です。

おそらく、読み取り専用ユーザーは実際には読み取り専用ではありませんか?正確には、読み取り専用と読み取り/書き込みのどちらが実装されていますか?私のアプリでは、おそらくデフォルトでフォームを読み取り専用に設定し、読み取り/書き込みユーザーに対してフォームのAllowedits / Allowadditions/AllowdeletionsをTrueに設定します。あなたが言ったことから、あなたはJetユーザーレベルのセキュリティを使用していると思います。おそらく、デフォルトのAdminユーザーは読み取り専用ユーザーであり、他のユーザー名は読み取り/書き込みユーザーです。したがって、すべての形式で、OnLoadイベントでこれを行うことができます。

  Me.AllowEdits = (CurrentUser()<>"Admin")
  Me.AllowDeletions = Me.AllowEdits
  Me.AllowAdditions = Me.AllowEdits

また、ユーザーレベルの制限をテーブル(バックエンドのみ、またはバックエンドとフロントエンドの両方)に適用し、読み取り専用の管理者ユーザーグループとユーザーユーザーグループを与えてから、1人のユーザーに読み取り/書き込みを与えることも賢明です。 。Jet ULSはNTFSセキュリティとは異なり、最も許容度の低いアクセス許可が優先されます。JetULSでは、最も許容度の高いアクセス許可が優先されます。そのため、管理者グループとユーザーグループの両方を読み取り専用にする(管理者にアクセス許可を与えない)必要があります。具体的には、ユーザー。つまり、すべてのアクセス許可はグループメンバーシップから継承されます)。

もちろん、これはバックエンドMDBのNTFSアクセス許可を介して試行されていないと想定しています。もしそうなら、それは大きな問題である可能性が高く、それを行うための正しい方法ではありません。あなたが言ったことから、これが起こっていることである可能性は低いと思われるので、私はそれについてこれ以上言いません。

しかし、私が最初に見るのは、いわゆる読み取り専用ユーザーが本当に読み取り専用であるかどうかです。

于 2009-07-26T21:25:07.570 に答える