分布式数据库定时同步问题之--SqlCommand不可序列化

简介: 近日,做一个分布式数据库定时同步的项目,也就是说有多个物理节点上的数据库需要在每天某时来同步表中的数据,对于某个指定节点上的某个表发生的变化(增量)可以通过对该表执行的SqlCommand来记录,当同步过程发生时,需要对其它所有节点上的同名表执行相同的SqlCommand。

    近日,做一个分布式数据库定时同步的项目,也就是说有多个物理节点上的数据库需要在每天某时来同步表中的数据,对于某个指定节点上的某个表发生的变化(增量)可以通过对该表执行的SqlCommand来记录,当同步过程发生时,需要对其它所有节点上的同名表执行相同的SqlCommand。由于,同步是定时发生的,所以增量SqlCommand就需要首先被保存起来,开始我们计划将其序列化后保存在数据库中,但是到运行时,问题来了,SqlCommand是不可序列化的!!!所有继承自IDbCommand的类都是不可序列化的,所有继承自IDbParameter的实现类都是不可序列化的。
    遇到了这个问题,是我们当初没有料想到的,看来要妥善的解决这个问题,否则,我们的设计和实现不可避免的要进行大量的修改!我们最后采用的解决方案是自己手写一个可以序列化的ESqlCommand,它可以和SqlCommand相互转换,就像这样:

            SqlCommand command  =   new  SqlCommand( this .cmdText , new  SqlConnection(connStr) , null ) ;
            
// 正向
            ESqlCommand esCommand  =   new  ESqlCommand(command) ;
            
// 反向
            SqlCommand command2  =  esCommand.ToSqlCommand(connStr) ;

    有了ESqlCommand之后,我们的设计几乎不需要修改,仅仅在增量序列化保存到数据库之前转换为ESqlCommand,而读出增量字段反序列化之后再转换为SqlCommand即可。
    下面给出ESqlCommand的实现(当然,不可避免的也要包含可序列化的ESqlParameter实现):

    #region  ESqlCommand
    
///   <summary>
    
///  ESqlCommand 可序列化的SqlCommand。System.Data.SqlClient.SqlCommand是不可序列化的
    
///   </summary>
    [Serializable]
    
public   class  ESqlCommand
    {
        
private  ESqlParameter[] esParas ;
        
private   string           cmdText ;
        
private  CommandType     cmdType ;

        
public  ESqlCommand(SqlCommand command)
        {
            
this .cmdText  =  command.CommandText ;
            
this .cmdType  =  command.CommandType ;

            
this .esParas  =   new  ESqlParameter[command.Parameters.Count] ;
            
int  index  =   0  ;
            
foreach (SqlParameter para  in  command.Parameters)
            {
                
this .esParas[index]  =   new  ESqlParameter(para) ;
                index
++  ;
            }
        }

        
public  SqlCommand ToSqlCommand( string  connStr)
        {
            SqlCommand command 
=   new  SqlCommand( this .cmdText , new  SqlConnection(connStr) , null ) ;
          

            
for ( int  i = 0  ;i < this .esParas.Length ;i ++ )
            {
                command.Parameters.Add(
this .esParas[i].ToSqlParameter()) ;
            }        
            
            command.CommandType 
=   this .cmdType ;
            
return  command ;            
        }
    }

    [Serializable]
    
public   class  ESqlParameter
    {
        
public  ESqlParameter(SqlParameter sPara)
        {
            
this .paraName  =  sPara.ParameterName ;
            
this .paraLen   =  sPara.Size ;
            
this .paraVal   =  sPara.Value ;
            
this .sqlDbType =  sPara.SqlDbType ;        
        }

        
public  SqlParameter ToSqlParameter()
        {
            SqlParameter para 
=   new  SqlParameter( this .paraName , this .sqlDbType , this .paraLen) ;
            para.Value 
=   this .paraVal ;

            
return  para ;
        }


        
#region  ParaName
        
private   string  paraName  =   ""  ; 
        
public   string  ParaName
        {
            
get
            {
                
return   this .paraName ;
            }
            
set
            {
                
this .paraName  =  value ;
            }
        }
        
#endregion
    
        
#region  ParaLen
        
private   int  paraLen  =   0  ; 
        
public   int  ParaLen
        {
            
get
            {
                
return   this .paraLen ;
            }
            
set
            {
                
this .paraLen  =  value ;
            }
        }
        
#endregion
    
        
#region  ParaVal
        
private   object  paraVal  =   null  ; 
        
public   object  ParaVal
        {
            
get
            {
                
return   this .paraVal ;
            }
            
set
            {
                
this .paraVal  =  value ;
            }
        }
        
#endregion         

        
#region  SqlDbType
        
private  SqlDbType sqlDbType  =  SqlDbType.NVarChar ; 
        
public  SqlDbType SqlDbType
        {
            
get
            {
                
return   this .sqlDbType ;
            }
            
set
            {
                
this .sqlDbType  =  value ;
            }
        }
        
#endregion

    }
    
#endregion

 

目录
相关文章
|
3月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
19天前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
2月前
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
3月前
|
运维 监控 NoSQL
【MongoDB 复制集秘籍】Secondary 同步慢怎么办?深度解析与实战指南,让你的数据库飞速同步!
【8月更文挑战第24天】本文通过一个具体案例探讨了MongoDB复制集中Secondary成员同步缓慢的问题。现象表现为数据延迟增加,影响业务运行。经分析,可能的原因包括硬件资源不足、网络状况不佳、复制日志错误等。解决策略涵盖优化硬件(如增加内存、升级CPU)、调整网络配置以减少延迟以及优化MongoDB配置(例如调整`oplogSize`、启用压缩)。通过这些方法可有效提升同步效率,保证系统的稳定性和性能。
83 4
|
3月前
|
存储 SQL 分布式数据库
OceanBase 入门:分布式数据库的基础概念
【8月更文第31天】在当今的大数据时代,随着业务规模的不断扩大,传统的单机数据库已经难以满足高并发、大数据量的应用需求。分布式数据库应运而生,成为解决这一问题的有效方案之一。本文将介绍一款由阿里巴巴集团自主研发的分布式数据库——OceanBase,并通过一些基础概念和实际代码示例来帮助读者理解其工作原理。
284 0
|
5天前
|
缓存 关系型数据库 MySQL
高并发架构系列:数据库主从同步的 3 种方案
本文详解高并发场景下数据库主从同步的三种解决方案:数据主从同步、数据库半同步复制、数据库中间件同步和缓存记录写key同步,旨在帮助解决数据一致性问题。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
高并发架构系列:数据库主从同步的 3 种方案
|
14天前
|
算法 大数据 数据库
云计算与大数据平台的数据库迁移与同步
本文详细介绍了云计算与大数据平台的数据库迁移与同步的核心概念、算法原理、具体操作步骤、数学模型公式、代码实例及未来发展趋势与挑战。涵盖全量与增量迁移、一致性与异步复制等内容,旨在帮助读者全面了解并应对相关技术挑战。
25 3
|
14天前
|
JSON 分布式计算 前端开发
前端的全栈之路Meteor篇(七):轻量的NoSql分布式数据协议同步协议DDP深度剖析
本文深入探讨了DDP(Distributed Data Protocol)协议,这是一种在Meteor框架中广泛使用的发布/订阅协议,支持实时数据同步。文章详细介绍了DDP的主要特点、消息类型、协议流程及其在Meteor中的应用,包括实时数据同步、用户界面响应、分布式计算、多客户端协作和离线支持等。通过学习DDP,开发者可以构建响应迅速、适应性强的现代Web应用。
|
29天前
|
SQL 关系型数据库 分布式数据库
Citus 简介,将 Postgres 转换为分布式数据库
【10月更文挑战第4天】Citus 简介,将 Postgres 转换为分布式数据库
73 4
|
21天前
|
SQL NoSQL MongoDB
一款基于分布式文件存储的数据库MongoDB的介绍及基本使用教程
一款基于分布式文件存储的数据库MongoDB的介绍及基本使用教程
35 0