[Syniti(旧DBMoto)]レコード競合(コンフリクト)発生時のレコード内容を出力する方法


データベースレプリケーションツールSyniti(旧DBMoto)では、双方向のデータベース差分連携(シンクロナイゼーション)を行うことも可能です。これにより、双方のデータベースで更新が発生する連携システムなどの運用要件にも対応できます。

また、双方向連携を行う場合は、双方のデータベースで同一レコードに対しての更新が同タイミングで行われることにより、レプリケーション対象レコードの競合(コンフリクト)が発生する可能性があります。

Synitiではこの競合が発生した場合に、どちらのデータベースのレコードを優先するかや、更新タイムスタンプの早い/遅いで決定するなどのオプション機能が標準で搭載されていますので、これにより競合が発生しても、データの不整合が発生しないような仕様動作となっています。
※これらの競合回避オプションはGUI上で設定可能です。

さらに、スクリプトを使用することで競合が発生したレコードをログに出力させることやメール通知を行うことも可能です。今回の記事ではその手法について紹介します。

SynitiではVBとC#のスクリプトに対応しておりますが、今回はVBを用いるので、まずは、Syniti管理画面左上にあるグローバルスクリプトボタンをクリックし、ポップアップされたSynitiグローバルスクリプト画面でスクリプト言語をVBに設定します。

競合判定でスクリプトを使用するため、双方向レプリケーションのプロパティ画面を開き、優先 >ミラーリングオプション > 競合回避項目をUseScriptに変更します。

その後、レプリケーションスクリプトに下記スクリプトをコピーします。

Imports System
Imports System.Data
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript

Namespace DBRS
    Public Class ReplicationScript : Inherits IReplicationScript
        Public Overrides Function Replication_onConflict(recSource As IRecord, recTarget As IRecord) As IRecord
            AddLog("コンフリクトが発生しました", 1, recSource, 4)
            SendMail("DBMoto通知メール", "コンフリクトが発生しました")
            Return recSource
        End Function
    End Class
End Namespace

Replication_onConflict
コンフリクト発生時に呼び出されるイベント処理です。
コンフリクトオプションが UseScript に設定されている場合にのみ有効となります。

AddLog
ログファイルに任意のメッセージを出力します。
第1引数はログメッセージ
第2引数はエラーレベル(0情報1警告2エラー)
第3引数はソース(recSource)かターゲット(recTarget)のどちらか
第4引数は第3引数の情報として、何を出力するかを指定します。
4の場合は、競合が発生したレコード内容を出力します。

SendMail
メール通知を行います。第1引数は件名、第2引数が本文です。
メールサーバの設定はレプリケーションオプション画面の
メールタブにて設定可能です。

Return~
競合発生時の判定の指定で recSource はソース優先、recTarget はターゲット優先となります。更新の先勝・後勝を実施したい場合はタイムスタンプの比較で条件分岐とします。

例 :後勝としたい場合

Imports System
Imports System.Data
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript

Namespace DBRS
    Public Class ReplicationScript : Inherits IReplicationScript
        Public Overrides Function Replication_onConflict(recSource As IRecord, recTarget As IRecord) As IRecord
            AddLog("コンフリクトが発生しました", 1, recSource, 4)
            SendMail("DBMoto通知メール", "コンフリクトが発生しました")
            If recSource.GetLogValue(enmLogFields.TransactionTS).ToString() > recTarget.GetLogValue(enmLogFields.TransactionTS).ToString() Then
                Return recSource
            Else
                Return recTarget
            End If
        End Function
    End Class
End Namespace

スクリプト設定後、実際に競合を発生させてみると、下記のようにDBMoto画面の履歴ビューワ上でもコンフリクトしたレコードが出力されていることが確認できます。

関連したトピックス

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください