Imports System
Imports System.Data
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript
Namespace DBRS
Public Class ReplicationScript : Inherits IReplicationScript
Public Overrides Sub Record_onAfterMapping( recSource As DBMotoPublic.IRecord, recTarget As DBMotoPublic.IRecord, ByRef AbortRecord As Boolean, ByRef DisableReplication As Boolean)
' ソーステーブルカラム名の変数
Dim strField As String
' ソース側へUpdateクエリが実行された時
If (recSource.OperationType = enmOperationType.Update) Then
' "DFLUG"というカラム名を指定し、値を取得
strField = CType(recSource.GetValueAfter("DFLUG").ToString(), Integer)
End If
' "DFLUG"の値が"1"だった場合、ターゲットのレコードにDeleteクエリを発行
If (strField = "1") Then
recTarget.OperationType = enmOperationType.Delete
End If
End Sub
End Class
End Namespace
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
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
Public Shared Sub AddLog (str As String, eType As enmLogMessageType,
record As DBMotoPublic.IRecord, eRecordImage As enmRecordImage)
例:
Public Overrides Sub Record_onAfterMapping(recSource As IRecord, recTarget As IRecord,
ByRef AbortRecord As Boolean)
Dim S as String
AddLog("The current record has been inserted", 0, recSource, 4)
End Sub
Public Shared Sub SendMail (sSubject As String, sMessageBody As String, sRcptTo As String)
例:
SendMail ("Message from Syniti DR",
"An error occurred that requires intervention by the system administrator.",
"somebody@company.com")
C#
public static void SendMail(string sSubject, string sMessageBody, string sRcptTo)
例:
SendMail("Message from Syniti DR",
"An error occurred that requires intervention by the system administrator.",
"somebody@company.com")
Public Shared Sub SendMail (sSubject As String, sMessageBody As String,
sSMTPServer As String, sRcptFrom As String, sRcptTo As String)
例:
SendMail ("Message from Syniti DR",
"An error occurred that requires intervention by the system administrator.",
"www.smtp.com", "DBMoto Notification Agent", "somebody@company.com")
C#
public static void SendMail(string sSubject, string sMessageBody, string sSMTPServer,
string sRcptFrom, string sRcptTo)
例:
SendMail("Message from Syniti DR",
"An error occurred that requires intervention by the system administrator.",
"www.smtp.com", "Syniti DR Notification Agent", "somebody@company.com")
Public Shared Function GetRecordInfo (record As DBMotoPublic.IRecord, eRecordImage As enmRecordImage) As String
例:
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript
Namespace DBRS
Public Class ReplicationScript : Inherits IReplicationScript
Public Overrides Sub Record_onAfterMapping(recSource As IRecord, recTarget As IRecord,
ByRef AbortRecord As Boolean)
Dim S as String = GetRecordInfo(recSource, enmRecordImage.KeyValues)
AddLog("The current record has been inserted: " + S, 0)
End Sub
End Class
End Namespace
C#
public static string GetRecordInfo(DBMotoPublic.IRecord record, enmRecordImage eRecordImage)
例:
using System;
using System.Data;
using DBMotoPublic;
using DBMotoScript;
namespace DBRS
{
public class ReplicationScript : IReplicationScript
{
public override void Record_onAfterMapping(DBMotoPublic.IRecord recSource,
DBMotoPublic.IRecord recTarget, ref bool AbortRecord)
{
string = GlobalScript.GetRecordInfo(recSource, enmRecordImage.KeyValues);
GlobalScript.AddLog("The current record has been inserted: " + s, 0);
}
}
}
Public Shared Function GetJSONRecordInfo(Of T)(ByVal jsonString As String) As T
Public Shared Function GetJSONRecordInfo(ParamArray ByVal args() As Object) As String
Public Shared Function GetJSONRecordInfo(Of T)(ByVal value As T) As String
Public Shared Function GetJSONRecordInfo(Of T)(ByVal jsonString As String) As T
C#
public static string GetJSONRecordInfo(DBMotoPublic.IRecord record, enmRecordImage eRecordImage)
public static string GetJSONRecordInfo(params object[] args)
public static string GetJSONRecordInfo(T value)
public static T GetJSONRecordInfo(string jsonString)
この関数は、ReceiverInfo型の値を返します。クラスの定義は次のとおりです。 Public Class ReceiverInfo Public JournalLibrary As String Public JournalName As String Public ReceiverLibrary As String Public ReceiverName As String End Class
VB.NET
Public Shared Function GetReceiversInUse (ConnectionName As String, IsSource As Boolean, OnlyActiveReplications As Boolean) As ReceiverInfo()
例:
Imports Microsoft.VisualBasic
Imports DBMotoPublic
Imports DBMotoScript
Imports DBRS.GlobalScript
Imports System.Data
Namespace DBRS
Public Class ReplicationScript : Inherits IReplicationScript
Public Overrides Sub LogReader_onBeforeMirroring(bSource as Boolean)
Dim arrReceivers As ReceiverInfo() = GetReceiversInUse ("AS400", True, True)
Dim recInfo As ReceiverInfo
For Each recInfo in arrReceivers
AddLog("Receiver in use: " + recInfo.JournalLibrary + "." + recInfo.JournalName +
"/" + recInfo.ReceiverLibrary + "." + recInfo.ReceiverName, 0)
Next
End Sub
End Class
End Namespace
C#
public static ReceiverInfo[] GetReceiversInUse(string ConnectionName, bool IsSource, bool OnlyActiveReplications)
例:
using System;
using System.Data;
using DBMotoPublic;
using DBMotoScript;
namespace DBRS
{
public class ReplicationScript : IReplicationScript
{
public override void LogReader_onBeforeMirroring(bool bSource)
{
ReceiverInfo[] arrReceivers = GlobalScript.GetReceiversInUse("AS400", true, true);
foreach (ReceiverInfo recInfo in arrReceivers)
{
GlobalScript.AddLog("Receiver in use: " + recInfo.JournalLibrary + "." + recInfo.JournalName
+ "/" + recInfo.ReceiverLibrary + "." + recInfo.ReceiverName, 0);
}
}
}
}
Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String,
ByVal recTarget As DBMotoPublic.IRecord,
ByVal e As Exception,
ByRef bRecoverReplication As Boolean,
ByRef bDisableReplication As Boolean,
ByRef bRetryExecute As Boolean,
ByRef iSleep As Integer,
ByVal iIteration As Integer)
※関数名MyErrorHandlerは変更可能です。
例:
Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String,
ByVal recTarget As DBMotoPublic.IRecord,
ByVal e As Exception,
ByRef bRecoverReplication As Boolean,
ByRef bAbortRecord As Boolean,
ByRef bDisableReplication As Boolean,
ByRef bRetryExecute As Boolean,
ByRef iSleep As Integer,
ByVal iIteration As Integer)
Dim s As String
s = s + "-- Called MyErrorHandler to catch the error in replication or group '"
+ sReplOrGroupName + "'" + Environment.NewLine
s = s + "-- Exception: " + e.ToString() + Environment.NewLine
s = s + "-- Iteration: " + iIteration.ToString()
bRetryExecute = Falsehttps://www.climb.co.jp/blog_dbmoto/wp-admin/post-new.php?post_type=rtbs_tabs#
' Disable replication if the error is a SQL Server timeout error
If e.Message.IndexOf("System.Data.SqlClient.SqlException: Timeout expired.") = 0 Then
bAbortRecord = True
bDisableReplication = True
s = s + " - Replication disabled"
Else ' retry
If iIteration = 3 Then
bRetryExecute = False
s = s + " - No Retry"
Else
bRetryExecute = True
iSleep = 3000
s = s + " - Try Again after " + (iSleep/1000).ToString() + " seconds."
End If
End If
IGlobalScript.AddLog (s, 1)
End Sub
C#
[GlobalEventsAttribute("Record_OnExecuteError", "Define a general event for the event OnExecuteError")]
public static void MyErrorHandler(string sReplOrGroupName,
DBMotoPublic.IRecord recTarget,
Exception e,
ref bool bRecoverReplication,
ref bool bDisableReplication,
ref bool bRetryExecute,
ref int iSleep,
int iIteration)
例:
public class GlobalEvents : IGlobalEvents
{
[GlobalEventsAttribute("Record_OnExecuteError", "Define a general event for the event EventName")]
public static void MyErrorHandler(String sReplOrGroupName, DBMotoPublic.IRecord recTarget, Exception e,
ref bool bRecoverReplication, ref bool bAbortRecord, ref bool bDisableReplication,
sref Boolean bRetryExecute, ref int iSleep, int iIteration)
{
String s = null;
s = s + "-- Called MyErrorHandler to catch the error in replication or group '" + sReplOrGroupName + "'"
+ Environment.NewLine;
s = s + "-- Exception: " + e.ToString() + Environment.NewLine;
s = s + "-- Iteration: " + iIteration.ToString();
bRetryExecute = false;
// Disable replication if the error is a SQL Server timeout error
if (e.Message.IndexOf("System.Data.SqlClient.SqlException: Timeout expired.") = 0) {
bAbortRecord = true;
bDisableReplication = true;
s = s + " - Replication disabled";
}
else { // retry
if (iIteration >= 3) {
bRetryExecute = false;
s = s + " - No Retry";
}
else {
bRetryExecute = true;
iSleep = 3000;
s = s + " - Try Again after " + (iSleep / 1000).ToString() + "seconds.";
}
}
IGlobalScript.AddLog(s, 1);
}
Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String,
ByVal recSource As DBMotoPublic.IRecord,
ByVal recTarget As DBMotoPublic.IRecord,
ByVal e As Exception,
ByRef bAbort As Boolean,
ByRef bRecoverReplication As Boolean,
ByRef bDisableReplication As Boolean,
ByRef bRetryExecute As Boolean,
ByRef iSleep As Integer,
ByVal iIteration As Integer
※関数名MyErrorHandlerは変更可能です。
例:
Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String,
ByVal recSource As DBMotoPublic.IRecord,
ByVal recTarget As DBMotoPublic.IRecord,
ByVal e As Exception,
ByRef bAbort As Boolean,
ByRef bRecoverReplication As Boolean,
ByRef bAbortRecord As Boolean,
ByRef bDisableReplication As Boolean,
ByRef bRetryExecute As Boolean,
ByRef iSleep As Integer,
ByVal iIteration As Integer)
Dim s As String
s = s + "-- Called MyErrorHandler to catch the error in replication or group '"
+ sReplOrGroupName + "'" + Environment.NewLine
s = s + "-- Exception: " + e.ToString() + Environment.NewLine
s = s + "-- Iteration: " + iIteration.ToString()
bRetryExecute = False
' Disable replication if the error is a syntax error
If e.Message.Contains("Error applying the mapping for the target field") Then
bAbortRecord = True
bDisableReplication = True
s = s + " - Replication disabled"
Else ' retry
If iIteration = 3 Then
bRetryExecute = False
s = s + " - No Retry"
Else
bRetryExecute = True
iSleep = 3000
s = s + " - Try Again after " + (iSleep/1000).ToString() + " seconds."
End If
End If
IGlobalScript.AddLog (s, 1)
End Sub
C#
[GlobalEventsAttribute("Record_OnMappingError", "Define a general event for the event OnMappingError")]
public static void MyErrorHandler(string sReplOrGroupName,
DBMotoPublic.IRecord recSource,
DBMotoPublic.IRecord recTarget,
Exception e,
ref bool bAbort,
ref bool bRecoverReplication,
ref bool bDisableReplication,
ref bool bRetryExecute,
ref int iSleep,
int iIteration)
例:
public class GlobalEvents : IGlobalEvents
{
[GlobalEventsAttribute("Record_MappingError", "Define a general event for the event EventName")]
public static void MyErrorHandler(String sReplOrGroupName, DBMotoPublic.IRecord recSource, DBMotoPublic.IRecord recTarget, Exception e,
ref bool bAbort, ref bool bRecoverReplication, ref bool bAbortRecord, ref bool bDisableReplication,
sref Boolean bRetryExecute, ref int iSleep, int iIteration)
{
String s = null;
s = s + "-- Called MyErrorHandler to catch the error in replication or group '" + sReplOrGroupName + "'"
+ Environment.NewLine;
s = s + "-- Exception: " + e.ToString() + Environment.NewLine;
s = s + "-- Iteration: " + iIteration.ToString();
bRetryExecute = false;
// Disable replication if the error is a syntax error
if (e.Message.Contains("Error applying the mapping for the target field")) {
bAbortRecord = true;
bDisableReplication = true;
s = s + " - Replication disabled";
}
else { // retry
if (iIteration >= 3) {
bRetryExecute = false;
s = s + " - No Retry";
}
else {
bRetryExecute = true;
iSleep = 3000;
s = s + " - Try Again after " + (iSleep / 1000).ToString() + "seconds.";
}
}
IGlobalScript.AddLog(s, 1);
}
Public Shared Sub MyErrorHandler (ByVal sReplOrGroupName As String, ByVal sMessage As String,
ByVal bWillDisable As Boolean, ByVal eReplStatus As enmReplStatus)
※関数名MyErrorHandlerは変更可能です。
例:
_
Public Shared Sub MyGlobalEvent (ByVal sReplicationName As String, ByVal sMessage As String,
ByVal bWillBeDisabled As Boolean, ByVal eReplStatus As enmReplStatus)
Dim s As String
s = DateTime.Now.ToString() + Environment.NewLine + Environment.NewLine
s = s + "Error in replication '" + sReplicationName + "'"
+ Environment.NewLine + Environment.NewLine
s = s + "Replication Status: " + eReplStatus.ToString() + Environment.NewLine
+ Environment.NewLine
s = s + sMessage + Environment.NewLine + Environment.NewLine
If bWillBeDisabled Then
s = s + "The replication will be disabled." + Environment.NewLine + Environment.NewLine
End If
s = s + "-----------------------------------------------------------------" + Environment.NewLine
s = s + " This is an automatic message generated by the Syniti DR script" + Environment.NewLine
s = s + "-----------------------------------------------------------------" + Environment.NewLine
IGlobalScript.SendMail ("Syniti DR Error", s)
End Sub
C#
[GlobalEventsAttribute("Replication_OnError", "Define a general event for the event Replication_OnError")]
public static void MyErrorHandler(string sReplOrGroupName, string sMessage,
bool bWillDisable, enmReplStatus eReplStatus)
例:
[GlobalEventsAttribute("Replication_OnError", "General event for the event OnError")]
public static void MyGlobalEvent(String sReplicationName, String sMessage, Boolean bWillBeDisabled,
enmReplStatus eReplStatus)
{
String s = null;
s = DateTime.Now.ToString() + Environment.NewLine + Environment.NewLine;
s = s + "Error in replication '" + sReplicationName + "'"
+ Environment.NewLine + Environment.NewLine;
s = s + "Replication Status: " + eReplStatus.ToString() + Environment.NewLine
+ Environment.NewLine;
s = s + sMessage + Environment.NewLine + Environment.NewLine;
if (bWillBeDisabled)
{
s = s + "The replication will be disabled." + Environment.NewLine + Environment.NewLine;
}
s = s + "---------------------------------------------" + Environment.NewLine;
s = s + " This automatic message is generated by the Syniti DR script" + Environment.NewLine;
s = s + "---------------------------------------------" + Environment.NewLine;
IGlobalScript.SendMail("Syniti DR Error", s);
}
ReplicationManager_onStart
パラメータと解説
このイベントは、レプリケーションエージェントの起動時に発生します。 Syniti DRログに通知メッセージを追加したり、管理者に電子メールを送信したりするために使用できます。 イベントのハンドラーを作成するには、クラスヘッダー「Public Class GlobalEvents:Inherits IGlobalEvents」内にカーソルを置き、例をガイドラインとして使用してハンドラーを定義します。
_
Public Shared Sub OnStart ()
例:
_
Public Shared Sub OnStart ()
Dim s As String
s = s + "-- Message from Syniti DR - START"
s = s + "-----------------------------------------------------------------"
+ Environment.NewLine
s = s + "- This is an automatic message generated by the Syniti DR
script -" + Environment.NewLine
s = s + "-----------------------------------------------------------------"
+ Environment.NewLine IGlobalScript.SendMail
("Replication Manager Message", s)
End Sub
C#
[GlobalEventsAttribute("ReplicationManager_OnStart", "Standard event for the event OnStart")]
public static void OnStart()
例:
[GlobalEventsAttribute("ReplicationManager_OnStart", "Standard event for the event OnStart")]
public static void OnStart()
{
String s = null;
s = s + "-- Message from Syniti DR - START";
s = s + "-------------------------------------------------------" + Environment.NewLine;
s = s + "- This is an automatic message generated by the Syniti DR script -" + Environment.NewLine;
s = s + "-------------------------------------------------------" + Environment.NewLine;
IGlobalScript.SendMail("Replication Manager Message", s);
}
ReplicationManager_onStop
パラメータと解説
このイベントは、レプリケーションエージェントが停止したときに発生します。 Syniti DRログに通知メッセージを追加したり、管理者に電子メールを送信したりするために使用できます。 イベントのハンドラーを作成するには、クラスヘッダー「Public Class GlobalEvents:Inherits IGlobalEvents」内にカーソルを置き、以下の例をガイドラインとして使用してハンドラーを定義します。
_
Public Shared Sub OnStop ()
例:
Public Shared Sub OnStop ()
Dim s As String
s = s + "-- Message from Syniti DR - STOP"
s = s + "---------------------------------------------------------" + Environment.NewLine
s = s + "This is an automatic message generated by the Syniti DR script -" + Environment.NewLine
s = s + "--------------------------------------------------------"
+ Environment.NewLine
IGlobalScript.SendMail ("Replication Manager Message", s)
End Sub
C#
[GlobalEventsAttribute("ReplicationManager_OnStop", "Standard event for the event OnStop")]
public static void OnStop()
例:
[GlobalEventsAttribute("ReplicationManager_OnStop", "Standard event for the event OnStop")]
public static void OnStop()
{
String s = null;
s = s + "-- Message from Syniti DR - STOP";
s = s + "--------------------------------------------------------" + Environment.NewLine;
s = s + "- This is an automatic message generated by the Syniti DR script -" + Environment.NewLine;
s = s + "---------------------------------------------------------" + Environment.NewLine;
IGlobalScript.SendMail("Replication Manager Message", s);
}
1.Syniti Data Replication (旧DBMoto)コンソールにてメタデータを右クリックし、グローバルスクリプトを選択します。デフォルトで言語にはC#が選択されています。
using System;
using System.Data;
using DBMotoPublic;
using DBMotoScript;
namespace DBRS
{
public class GlobalScript : IGlobalScript
{
}
public class MappingRule : IMappingRule
{
}
public class GlobalEvents : IGlobalEvents
{
}
}
2. GlobalScriptクラスで、次の例のように関数を宣言します
public static DateTime DateConvert(int intDate){
int cyy;
int yyyy;
int mm;
int dd;
cyy = (int)(intDate / 10000);
mm = (int)((intDate - cyy * 10000) / 100);
dd = intDate % 100;
if (cyy < 100)
yyyy = 1900 + cyy;
else
yyyy = 2000 + (cyy % 100);
DateTime dc = new DateTime(yyyy, mm, dd);
return dc;
}
[GlobalEventsAttribute("Record_OnExecuteError", "Define a general event for the event EventName")]
public void MyErrorHandler(String sReplOrGroupName, DBMotoPublic.IRecord recTarget, Exception e,
ref Boolean bRetryExecute, ref int iSleep, int iIteration)
{
}
米調査会社ガートナーが今夏に発表したレポート『The Future of Database Management Systems is Cloud!(データベース管理システムの未来はクラウド)』によれば、データベースをクラウドに置く企業が飛躍的に増えており、同分野の市場規模は2017年から2018年にかけて18.4%拡大、その68%はクラウド上のDBMSだといいます。市場拡大はAmazon
AWSとMicrosoft Azureが牽引し、その2社で全体の75%を占めますが、両社の新規ビジネスはほぼ100%クラウド
ベースだと報告されています。
現実的には、すでに稼働中の業務システムに細かな改善が繰り返し追加される開発環境において、まるでTo
Be or Not To Beのように、オンプレミスかクラウドの二者択一を迫るのは無理があります。現場はそんなに単純で恵まれた環境ではないと、ITチームの悲鳴が聞こえる気がします。データベースも各種アプリケーションもハイブリッド環境での可搬性と拡張性を目指すことが、もっとも現実的で合理的な戦略なはずで、それをサポートできるサービスの需要が今後もっとも見込まれるのではないでしょうか。
Syniti Data Replication (旧DBMoto)がレコードの列に番号を付ける方法は、ソースまたはターゲットの列の順序と必ずしも同じではありません。たとえば、一部のフィールドがマップされていない場合、それらはRecordBeforeまたはRecordAfter構造から除外されるため、列は順序番号と数値的に一致しません。
db tech showcase Tokyo 2018でのプレゼンテーション: 昨今オンプレのOracleからPostgreSQL, MySQL等オープン系のデータベースへの移行、またクラウド上のデータベースへの移行を検討されているユーザに異種リアルタイム・データベース・レプリケーションツール「DBMoto」を活用した事例をご紹介します。また古いOracle バージョンから最新Oracleバージョンへの移行手法・事例もご紹介します。またStambiaというユニークなETLツールもご紹介しています。DBMotoのお問い合わせは 03-3660-9336 までお願いします。