分布式数据库定时同步问题之--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

 

目录
相关文章
|
10月前
|
数据采集 缓存 NoSQL
分布式新闻数据采集系统的同步效率优化实战
本文介绍了一个针对高频新闻站点的分布式爬虫系统优化方案。通过引入异步任务机制、本地缓存池、Redis pipeline 批量写入及身份池策略,系统采集效率提升近两倍,数据同步延迟显著降低,实现了分钟级热点追踪能力,为实时舆情监控与分析提供了高效、稳定的数据支持。
421 1
分布式新闻数据采集系统的同步效率优化实战
|
10月前
|
存储 监控 分布式数据库
ClickHouse分布式数据库动态伸缩(弹性扩缩容)的实现
实现ClickHouse数据库的动态伸缩需要持续的维护和精细的操作。从集群配置到数据迁移,再到监控和自动化,每一步都要仔细管理以确保服务的可靠性和性能。这些活动可以显著提高应用的响应性和成本效率,帮助业务根据实际需求灵活调整资源分配。
516 10
|
11月前
|
存储 关系型数据库 分布式数据库
【赵渝强老师】基于PostgreSQL的分布式数据库:Citus
Citus 是基于 PostgreSQL 的开源分布式数据库,采用 shared nothing 架构,具备良好的扩展性。它以插件形式集成,部署简单,适用于处理大规模数据和高并发场景。本文介绍了 Citus 的基础概念、安装配置步骤及其在单机环境下的集群搭建方法。
925 2
|
12月前
|
关系型数据库 MySQL Linux
实现MySQL数据库的定时自动备份脚本。
拿走,不谢,这个脚本配方(指引)保证你的数据库数据像蛋糕店一样地天天更新,还能确保老旧的蛋糕(数据)不会堆积满仓库。这下可好,数据安全有保障,数据库管理员也能轻松一点,偶尔闲下来的时候,煮杯咖啡,看个剧岂不美哉?别忘了偶尔检查一下你的自动备份是否正常工作,以防万一蛋糕机器出了点小差错。
780 20
|
12月前
|
NoSQL Java Redis
分布式锁—6.Redisson的同步器组件
Redisson提供了多种分布式同步工具,包括分布式锁、Semaphore和CountDownLatch。分布式锁包括可重入锁、公平锁、联锁、红锁和读写锁,适用于不同的并发控制场景。Semaphore允许多个线程同时获取锁,适用于资源池管理。CountDownLatch则用于线程间的同步,确保一组线程完成操作后再继续执行。Redisson通过Redis实现这些同步机制,提供了高可用性和高性能的分布式同步解决方案。源码剖析部分详细介绍了这些组件的初始化和操作流程,展示了Redisson如何利用Redis命令和
|
存储 关系型数据库 MySQL
利用Cron表达式实现MySQL数据库的定时备份
以上就是如何使用Cron表达式和mysqldump命令实现MySQL数据库的定时备份。这种方法的优点是简单易用,而且可以根据需要定制备份的时间和频率。但是,它也有一些限制,例如,它不能备份MySQL服务器的配置文件和用户账户信息,也不能实现增量备份。如果需要更复杂的备份策略,可能需要使用专门的备份工具或服务。
361 15
|
SQL 存储 分布式数据库
分布式存储数据恢复—hbase和hive数据库数据恢复案例
分布式存储数据恢复环境: 16台某品牌R730xd服务器节点,每台服务器节点上有数台虚拟机。 虚拟机上部署Hbase和Hive数据库。 分布式存储故障: 数据库底层文件被误删除,数据库不能使用。要求恢复hbase和hive数据库。
483 12
|
SQL 运维 关系型数据库
体验用分布式数据库突破资源瓶颈,完成任务领智能台灯!
体验用分布式数据库突破资源瓶颈,完成任务领智能台灯!
|
SQL 数据建模 BI
【YashanDB 知识库】用 yasldr 配置 Bulkload 模式作单线程迁移 300G 的业务数据到分布式数据库,迁移任务频繁出错
问题描述 详细版本:YashanDB Server Enterprise Edition Release 23.2.4.100 x86_64 6db1237 影响范围: 离线数据迁移场景,影响业务数据入库。 外场将部分 NewCIS 的报表业务放到分布式数据库,验证 SQL 性能水平。 操作系统环境配置: 125G 内存 32C CPU 2T 的 HDD 磁盘 问题出现的步骤/操作: 1、部署崖山分布式数据库 1mm 1cn 3dn 单线启动 yasldr 数据迁移任务,设置 32 线程的 bulk load 模式 2、观察 yasldr.log 是否出现如下错