Takenoff Labs » Notes/Domino » DB設計 » ソフトロックにまつわる問題点

[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

ヘッダーと相性が悪い?

ノーツにはフォームの一部を固定できる機能(フォームのプロパティの「フォームにヘッダーを追加」)がありますが、これを有効にしている場合、ソフトロックが残ってしまう現象が起きたことがあります。

この機能のみでは再現されないようなので、他の要因が重なって発生したものと思われますが、少なくとも「フォームにヘッダーを追加」のチェックを外したら、その後は一切起きなくなったので、これが一因となったことは間違いないと思います。

もし頻繁にロックが残り、「フォームにヘッダーを追加」を有効にしている場合は、無効にしていみることをおすすめいたします。

1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading...

トラックバックURL :

Navigation

前の記事(カテゴリ内):

次の記事(カテゴリ内):

前の記事(日付順):

次の記事(日付順):

トラックバック

トラックバックはありません

コメント

コメントはありません

※コメントは承認制となっております。管理者が承認するまで表示されません。申し訳ありませんが、投稿が表示されるまでしばらくお待ちください。





(以下のタグが使えます)
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

For spam filtering purposes, please copy the number 8636 to the field below: