C# 后台服务监控SQL Server数据库表改动并同步到MySQL数据库表

需求

  1. 将A服务器的sql server数据库item_mst表的数据同步到MySQL数据库Part表
  2. 监控Item_mst表中item,description,overview 的更改并同步到MySQL数据库

 

针对需求一,基本就是执行一次,单独写了个winform用来做这事

针对需求二,写了个Windows service app

 

Nuget安装

 

C# 后台服务监控SQL Server数据库表改动并同步到MySQL数据库表_第1张图片

Dapper就是个orm

Serilog用来记log

SQLTableDependency用来检测表的改动,文档地址:https://github.com/christiandelbianco/monitor-table-change-with-sqltabledependency

使用这个别忘了执行 alter database [] set enable_broker with rollback immediate;

  1. 创建service
  2. 添加安装程序
  3. 如何安装service

Create a Windows service app

https://docs.microsoft.com/en-us/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer

 

How to: Add Installers to Your Service Application

https://docs.microsoft.com/zh-cn/dotnet/framework/windows-services/how-to-add-installers-to-your-service-application

How to: Install and uninstall Windows services

https://docs.microsoft.com/en-us/dotnet/framework/windows-services/how-to-install-and-uninstall-services

 

源码

目录结构

C# 后台服务监控SQL Server数据库表改动并同步到MySQL数据库表_第2张图片

Models文件夹里的ItemMst.cs文件

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SyncItemMstAllService.Models
{
    /// 
    /// table name: item_mst
    /// note: We do not need to specify all table columns but just the ones we are interested:
    /// 
    public class ItemMst
    {
        // internalNumber
        public string Item { get; set; }
        // name
        public string Description { get; set; }
        // description
        public string Overview { get; set; }
    }
}

App.config


    
    
  
  
    
      
Allow User Variables=True"这个东西我不知道干啥的,但我知道没他就会出现错误- -
不加会出现这样的情况
https://blog.csdn.net/qq_36279445/article/details/97126518

QMSSyncTiemMstService.cs

using System;
using System.Configuration;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.ServiceProcess;
using System.Threading.Tasks;
using Dapper;
using SyncItemMstAllService.Models;
using MySql.Data.MySqlClient;
using Serilog;
using TableDependency.SqlClient;
using TableDependency.SqlClient.Base.Enums;
using TableDependency.SqlClient.Base.EventArgs;
using System.Collections.Generic;

namespace QMSCSyncService
{
    public partial class QMSSyncItemMstService : ServiceBase
    {
        private SqlTableDependency _itemMstAllSyncDependency;
        private readonly string _jmp_app_ConnectionString;
        private readonly string _qms_mysql_ConnectionString;
        private readonly string _logFilesPath;
        private readonly string version = "1.0.20190730";

        public QMSSyncItemMstService()
        {
            InitializeComponent();
            _logFilesPath = ConfigurationManager.AppSettings["logFilesPath"];
            _jmp_app_ConnectionString = ConfigurationManager.ConnectionStrings["JMP_APP_SqlServerConnStr"].ConnectionString;
            _qms_mysql_ConnectionString = ConfigurationManager.ConnectionStrings["QMS_MySqlServerConnStr"].ConnectionString;

            Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.File($"{_logFilesPath}serviceLog.txt", rollingInterval: RollingInterval.Day)
                .CreateLogger();
        }

        protected override void OnStart(string[] args)
        {
            initItemMstAllSyncDependency();
            Log.Information($"QMSSyncService Started.Version{version}");
        }

        protected override void OnStop()
        {
            Log.Information("QMSSyncService Stopped.");
            try
            {

                if (_itemMstAllSyncDependency != null)
                {
                    _itemMstAllSyncDependency.Stop();
                    _itemMstAllSyncDependency.Dispose();
                }
            }
            catch (Exception ex)
            {
                Log.Error($"Error occur when stopping service, {ex.Message} {ex.Source}");
            }
        }

        private void initItemMstAllSyncDependency()
        {
            Log.Information($"run initItemMstAllSyncDependency");
            try
            {
                if (_itemMstAllSyncDependency != null)
                {
                    _itemMstAllSyncDependency.Stop();
                    _itemMstAllSyncDependency.Dispose();
                }
                _itemMstAllSyncDependency = new SqlTableDependency(_jmp_app_ConnectionString, "item_mst");
                _itemMstAllSyncDependency.OnChanged += ItemMstAllSyncDependency_OnChanged;
                _itemMstAllSyncDependency.OnError += ItemMstAllSyncDependency_OnError;
                _itemMstAllSyncDependency.Start();
            }
            catch (Exception ex)
            {
                Log.Error($"Init SqlTableDependency for ItemMstSyncs failed. {ex.Message} {ex.Source}");
                if (_itemMstAllSyncDependency != null)
                {
                    _itemMstAllSyncDependency.Stop();
                    _itemMstAllSyncDependency.Dispose();
                }
            } 
        private void ItemMstAllSyncDependency_OnChanged(object sender, RecordChangedEventArgs e)
        {
            if (e.ChangeType != ChangeType.None)
            {
                switch (e.ChangeType)
                {
                    case ChangeType.Insert:
                    case ChangeType.Update:
                        saveItemMst(e.Entity.Item, e.Entity.Description, e.Entity.Overview);
                        break;
                }
            }
        }

        private void saveItemMst(string item, string name, string description)
        {
            string UUID = Guid.NewGuid().ToString("D");
            DateTime dt = DateTime.Now;
            bool hasExisted = isExisted(item);
            if (name == null)
            {
                name = item;
            }
            string insertSql = $@"INSERT INTO `part` (
	                        `ParentPartId`,
	                        `PublisherId`,
	                        `UUID`,
	                        `Type`,
	                        `InternalNumber`,
	                        `SupplierNumber`,
	                        `Name`,
                            `Description`,
	                        `Rev`,
	                        `RevType`,
	                        `Level`,
	                        `Category`,
	                        `Status`,
	                        `CreatedAt`,
	                        `CreatedBy`,
	                        `IsDeleted` 
                        )
                        VALUES
	                        (
		                        0,
		                        149,
		                        @UUID,
		                        1,
		                        @item,
		                        NULL,
		                        @name,
		                        @description,
		                        'A',
		                        1,
		                        1,
		                        '',
		                        1,
		                        '{dt}',
		                        701,
		                        0
	                        );";
            string updateSql = $@"UPDATE `part` 
                                            SET
                                            `Name` = @name,
                                            `Description` = @description,
                                            `UpdatedAt` = '{dt}',
                                            `UpdatedBy` = '701'
                                            WHERE InternalNumber = @item";
            try
            {
                using (MySqlConnection qmsDBConnection = new MySqlConnection(_qms_mysql_ConnectionString))
                {
                    qmsDBConnection.Open();
                    using (MySqlCommand cmd = qmsDBConnection.CreateCommand())
                    {
                        try
                        {
                            cmd.CommandText = hasExisted ? updateSql : insertSql;
                            cmd.Parameters.Add(new MySqlParameter("@UUID", UUID));
                            cmd.Parameters.Add(new MySqlParameter("@name", name));
                            cmd.Parameters.Add(new MySqlParameter("@description", description));
                            cmd.Parameters.Add(new MySqlParameter("@item", item));
                            cmd.ExecuteNonQuery();
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"Sync from saveItemMst have error occur, {ex.Message} {ex.Source} { ex.StackTrace }");
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error($"Sync from saveItemMst have error occur, {ex.Message} {ex.Source} { ex.StackTrace }");
            }
        }
        private bool isExisted(string item)
        {
            string sSql = @"SELECT * FROM Part P WHERE P.PublisherId=149 AND P.InternalNumber = @item AND P.IsDeleted=0";
            try
            {
                using (MySqlConnection qmsDBConnection = new MySqlConnection(_qms_mysql_ConnectionString))
                {
                    qmsDBConnection.Open();
                    using (MySqlCommand cmd = new MySqlCommand(sSql, qmsDBConnection))
                    {
                        try
                        {
                            cmd.Parameters.Add(new MySqlParameter("@item", item));
                            object result = cmd.ExecuteScalar();
                            if (result != null)
                            {
                                return true;
                            }
                            return false;
                        }
                        catch (Exception ex)
                        {
                            Log.Error($"IsExisted have error occur, {ex.Message} {ex.Source} { ex.StackTrace }");
                            return false;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error($"IsExisted have error occur, {ex.Message} {ex.Source} { ex.StackTrace }");
                return false;
            }
        }
        } 
        private void ItemMstAllSyncDependency_OnError(object sender, TableDependency.SqlClient.Base.EventArgs.ErrorEventArgs e)
        {
            string innerException = e.Error.InnerException != null ? e.Error.InnerException.Message + e.Error.InnerException.Source : "";
            Log.Error($"ItemMstAllSyncDependency have error occur, {e.Error.Message} {e.Error.Source} { innerException }");
            try
            {
                this.OnStop();
                this.OnStart(null);
            }
            catch (Exception ex)
            {
                Log.Debug("Restart failed " + ex.Message + ex.Source);
            }
        }
    }
}

 

 

 

你可能感兴趣的:(C#,sql)