Microsoft Sync Framework SqlServerCE到自定义DBConnection没有捕获错误/清理更改

时间:2015-01-16 16:27:25

标签: .net sql-server-ce ibm-mq microsoft-sync-framework

原谅我对Microsoft Sync Framework的无知,因为我对它很陌生。但无论如何,我正在尝试开发一个自定义的仅上载同步过程,从Sql CE到与IBM websphere MQ接口的自定义InsertCommand派生类。

    public class MyServerSyncProvider : DbServerSyncProvider
{
            #region Constructors

    public MyServerSyncProvider()
    {
        base.Connection = CreateConnection();
        base.SyncAdapters.Add(MySyncAdapter);
    }
}
   class MySyncAdapter : SyncAdapter
{
    public MySyncAdapter(DbServerSyncProvider syncProvider)
    {
        base.TableName = "MyTable";

        base.InsertCommand = SyncHelper.CreateStoredProcCommand(syncProvider.Connection, "Queue Message Start:");

        var parm1 = base.InsertCommand.CreateParameter();
        parm1.ParameterName = "@parm1";
        parm1.Direction = ParameterDirection.Input;
        parm1.DbType = DbType.DateTime;
        parm1.SourceColumn = "source_column";
        base.InsertCommand.Parameters.Add(parm1);

        /////More Input parms

        var rowCount = base.InsertCommand.CreateParameter();
        rowCount.ParameterName = "@sync_row_count";
        rowCount.Direction = ParameterDirection.Output;
        rowCount.DbType = DbType.Int16;
        rowCount.SourceColumn = Microsoft.Synchronization.Data.SyncSession.SyncRowCount;
        base.InsertCommand.Parameters.Add(rowCount);

    }
}

这是通过覆盖ExecuteNonQuery方法来写入队列来实现的(我们从命令text / parameters创建消息)。

    Public Overrides Function ExecuteNonQuery() As Integer

    Dim mqConnectionObject As MQServerConnection = DirectCast(Me.Connection, MQServerConnection)
    ''get an instance of the MQServerFacade
    Dim mqServerFacade As MQTEPServerFacade = DirectCast(Me.Connection, MQServerConnection).MQServer
    If Me.Timeout > 0 Then
        mqServerFacade.Timeout = Me.Timeout
    End If
    Me.Parameters("@sync_row_count").Value = 0
    Try
        mqServerFacade.PutOnRequestQueue(CreateXmlDocumentForMQMessage())
        Me.Parameters("@sync_row_count").Value = 1
        Return 1
    Catch ex As Exception
        _logger.Write(TraceEventType.[Error], ex.Message)
        Return -1
    End Try
End Function

奇怪的是,这一切都奏效了。同步时,ApplyChanges函数正在创建新的MQ“连接”。然后,它遍历更改集中的每一行,正确填充参数并将消息放入队列。 (仅供参考,同步过程会抓取客户端表中的所有行,然后在同步完成后删除行。我认为不需要任何锚点。)

我遇到的问题是它没有完全正确地跟踪更改。例如,不会捕获可能在插入进程上发生的任何错误。正如您在上面的示例中所看到的,我必须将事务封装在try块中,否则同步将完全停止。我希望抓住错误,然后让进程点击ApplyChangeFailed监听器,然后继续下一行(见下文)。

    public class MySynchronizationService : DbSyncProviderService<MyServerSyncProvider>
{
    private static readonly string category = "MySynchronizationService";

    public MySynchronizationService()
    {
        this._serverSyncProvider.ApplyChangeFailed += new EventHandler<Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs>(_serverSyncProvider_ApplyChangeFailed);
    }

    void _serverSyncProvider_ApplyChangeFailed(object sender, Microsoft.Synchronization.Data.ApplyChangeFailedEventArgs e)
    {
        e.Action = Microsoft.Synchronization.Data.ApplyAction.Continue;
    }


    public override Microsoft.Synchronization.Data.SyncContext ApplyChanges(Microsoft.Synchronization.Data.SyncGroupMetadata groupMetaData, System.Data.DataSet changeSet, Microsoft.Synchronization.Data.SyncSession syncSession)
    {
        SetupContext(category, "ApplyChanges");
        Logger.Write(TraceEventType.Information, string.Format("Applying changes for {0} synchronization group",groupMetaData.GroupName));
        return base.ApplyChanges(groupMetaData, changeSet, syncSession);
    }
}

我听说@sync_row_count参数与此有关,但它似乎没有做任何事情。我的try catch确实阻止了行被放到队列中,但我没有得到任何反馈(syncStatistics只是说所有行都成功应用了)。

此外,同步过程在计时器上,在下一次尝试时,它会尝试同步上一批中的相同行。幸运的是,行状态设置为“已添加”,因此不再为这些行调用我的ExecuteNonQuery。这进一步巩固了插入数据(放入队列)以及Microsoft Sync Framework如何跟踪更改/错误之间存在一些脱节。

您将获得的任何帮助都将受到赞赏。我知道这个解决方案有点“开箱即用”,因为据我所知,Microsoft Sync Framework通常是数据库到数据库或文件到文件(而IBM MQ显然不是数据库),但如上所述,该过程是“工作”但我显然对我实施的内容感到不自在。

0 个答案:

没有答案