[Notes/Domino] ソフトロックにまつわる問題点
R6から、とくに何もしなくても排他制御(ソフトロック)ができるようになり、競合文書が発生しにくくなりました。まぁ、RDBでは当たり前の機能なんですけどね(^^;
しかしこのソフトロック、いろいろと問題点があります。以下に、わたしが経験したトラブルなどをまとめてみました。
文書がソフトロックされているかどうかが解らない
「文書がロックされていたら」という条件でプログラムを書きたい場合、ソフトロックではロックされているかどうかを取得する関数が用意されていないため、ソフトロックでは対処できません(x_x)
DBのプロパティのほうにある文書ロック機能を使えばよいのですが、こちらはこちらでいろいろと問題があるらしく、評判が悪いようです(なのでわたしは使ったことがありません(汗))。ロックされているかどうかが知りたい場合、自前でロック用文書を作るしかないのかもしれませんね……。
QueryModeChange で Continue = False してもロックが解除されない
文書自体に編集権限があっても、何らかの条件で文書を編集させたくない場合は多々あると思います(まぁ、セキュリティ的にはアレですけど、そんなに高度なことができるユーザーっていないし)。
その場合、QueryModeChange にて、読込モード→編集モードに移行する際に Continue = False することによってイベントをキャンセルする方法が手っ取り早いです。
が、これをやってしまうと、ソフトロックが解除されません(TT 文書を閉じるまではソフトロックがかかったままとなってしまします。
この現象を回避するには、以下のような関数を作って権限チェックを行うとよいと思います。(編集権限が無い場合、文書を開き直すことによって、ソフトロックを解除します。)
説明 | @関数式により、文書を編集できるかどうかチェックする(ソフトロック解除機能付き) |
---|---|
構文 | CheckCanEdit(uidoc As NotesUIDocument, Byval strFrml As String) As Boolean |
引数 | [in,---]uidoc ... 処理対象の文書(UI) [in,---]strFrml ... @関数式(式の評価結果が@Trueを返す場合のみ編集可とみなす) |
戻り値 | True ... 編集可、False ... 編集不可 |
ソースコード
Public Function CheckCanEdit(uidoc As NotesUIDocument, Byval strFrml As String) As Boolean Dim ws As New NotesUIWorkspace Dim ss As New NotesSession Dim db As NotesDatabase Dim doc As NotesDocument Dim varRet As Variant Dim strUnid As String Set db = ss.CurrentDatabase Set doc = uidoc.Document If uidoc.EditMode = True Then CheckCanEdit = True Exit Function End If varRet = Evaluate(strFrml, doc) If Cstr(varRet(0)) = "1" Then CheckCanEdit = True Exit Function Else strUnid = doc.UniversalID Call uidoc.Close() Delete doc Delete uidoc Set doc = db.GetDocumentByUNID(strUnid) Call ws.EditDocument(False, doc, False, "", False, True) Msgbox "編集権限が無いため、編集モードにできません", 0, "エラー" CheckCanEdit = False Exit Function End If End Function
例文
'この例では、Editorsフィールドに、文書を編集できるユーザーID・ロールなどがセットされていることを想定しています。
Sub Querymodechange(Source As Notesuidocument, Continue As Variant)
If CheckCanEdit(Source, {Editors *= @UserNamesList}) = False Then Exit Sub
End Sub
上記関数だけでは、ビューから直接編集モードにされた場合に、チェックを素通りしてしまいます。ユーザビリティは下がってしまいますが、以下のような関数でビューからの直接編集を禁止すると楽です。
説明 | ビューから直接編集モードにされるのを防ぐ |
---|---|
構文 | CheckDirectEdit(uidoc As NotesUIDocument, Continue As Variant) |
引数 | [in,---]uidoc ... 処理対象の文書(UI) [in,Out]Continue ... QueryOpen の Continue 引数をそのまま渡す |
ソースコード
Public Sub CheckDirectEdit(uidoc As NotesUIDocument, Continue As Variant) Dim doc As NotesDocument Set doc = uidoc.Document If uidoc.IsNewDoc = True Then Exit Sub If doc Is Nothing Then Exit Sub If doc.NoteID = "0" Then Exit Sub If uidoc.EditMode = True Then Msgbox "ビューから直接編集モードにしないでください", 0, "エラー" Continue = False End End If End Sub
例文
Sub Queryopen(Source As Notesuidocument, Mode As Integer, Isnewdoc As Variant, Continue As Variant) Call CheckDirectEdit(Source, Continue) End Sub
読込モードで開いているときに、他のユーザーが文書を更新して閉じた場合、ロックがかからない
文書を読込モードで開いてるときに、他のユーザーが「文書を編集モードにする→保存→閉じる」の処理を行った場合、読込モードで開いていた文書を編集モードにできてしまいます。で、その文書を保存すると競合になってしまいます(x_x)
まあ、これを不具合と言ってしまうのはちょっと酷かもしれませんが、実運用ではとっても困ってしまいます。
この現象を回避するには、以下のような関数を作成するとよいと思います。
※ 文書ID(@Text(@DocumentUniqueID))でソートされたビューを用意しておいてください。(ここでは「VwByUNID」が文書ID順のビューです。ビュー名が異なる場合は、「VwByUNID」を適切なビュー名に変更してください。)
※ この関数では文書を開き直していないため、ソフトロックが解除されませんが、まぁ「開き直してください」とメッセージ出しているので、解るでしょうっということで(^^; 気になる方は、無理矢理閉じちゃってもよいかもしれません。
説明 | 文書が更新されたかどうかをチェックする |
---|---|
構文 | CheckLastModified(uidoc As NotesUIDocument, Continue As Variant) |
引数 | [in,---]uidoc ... 処理対象の文書(UI) [in,Out]Continue ... QueryModeChange の Continue 引数をそのまま渡す |
ソースコード
Public Sub CheckLastModified(uidoc As NotesUIDocument, Continue As Variant) Dim db As NotesDatabase Dim vw As NotesView Dim doc As NotesDocument Dim docChk As NotesDocument Set doc = uidoc.Document Set db = doc.ParentDatabase Set vw = db.GetView("VwByUNID") If uidoc.EditMode = True Then Exit Sub End If Set docChk = vw.GetDocumentByKey(doc.UniversalID, True) If doc.LastModified <> docChk.LastModified Then Msgbox "他のユーザーによって文書が更新されました。文書を開き直してください。", 0, "お知らせ" Continue = False End End If End Sub
例文
Sub Querymodechange(Source As Notesuidocument, Continue As Variant) Call CheckLastModified(Source, Continue) End Sub
ヘッダーと相性が悪い?
ノーツにはフォームの一部を固定できる機能(フォームのプロパティの「フォームにヘッダーを追加」)がありますが、これを有効にしている場合、ソフトロックが残ってしまう現象が起きたことがあります。
この機能のみでは再現されないようなので、他の要因が重なって発生したものと思われますが、少なくとも「フォームにヘッダーを追加」のチェックを外したら、その後は一切起きなくなったので、これが一因となったことは間違いないと思います。
もし頻繁にロックが残り、「フォームにヘッダーを追加」を有効にしている場合は、無効にしていみることをおすすめいたします。
コメント
コメントはありません
※コメントは承認制となっております。管理者が承認するまで表示されません。申し訳ありませんが、投稿が表示されるまでしばらくお待ちください。