예제 #1
0
파일: DbPackage.cs 프로젝트: pjy612/X
        /// <summary>备份一批表到另一个库</summary>
        /// <param name="tables">表名集合</param>
        /// <param name="connName">目标连接名</param>
        /// <param name="syncSchema">同步架构</param>
        /// <returns></returns>
        public IDictionary <String, Int32> SyncAll(IDataTable[] tables, String connName, Boolean syncSchema = true)
        {
            if (connName.IsNullOrEmpty())
            {
                throw new ArgumentNullException(nameof(connName));
            }
            if (tables == null)
            {
                throw new ArgumentNullException(nameof(tables));
            }

            using var span = Tracer?.NewSpan("db:SyncAll", connName);

            var dic = new Dictionary <String, Int32>();

            if (tables.Length == 0)
            {
                return(dic);
            }

            // 同步架构
            if (syncSchema)
            {
                DAL.Create(connName).SetTables(tables);
            }

            try
            {
                foreach (var item in tables)
                {
                    try
                    {
                        dic[item.Name] = Sync(item, connName, false);
                    }
                    catch (Exception ex)
                    {
                        if (!IgnoreError)
                        {
                            throw;
                        }
                        XTrace.WriteException(ex);
                    }
                }
            }
            catch (Exception ex)
            {
                span?.SetError(ex, null);
                throw;
            }

            return(dic);
        }
예제 #2
0
파일: DbPackage.cs 프로젝트: pjy612/X
        /// <summary>同步单表数据</summary>
        /// <remarks>
        /// 把数据同一张表同步到另一个库
        /// </remarks>
        /// <param name="table">数据表</param>
        /// <param name="connName">目标连接名</param>
        /// <param name="syncSchema">同步架构</param>
        /// <returns></returns>
        public virtual Int32 Sync(IDataTable table, String connName, Boolean syncSchema = true)
        {
            if (connName.IsNullOrEmpty())
            {
                throw new ArgumentNullException(nameof(connName));
            }
            if (table == null)
            {
                throw new ArgumentNullException(nameof(table));
            }

            using var span = Tracer?.NewSpan("db:Sync", $"{table.Name}->{connName}");

            var dal = DAL.Create(connName);

            var writeDb = new WriteDbActor
            {
                Table           = table,
                Dal             = dal,
                IgnorePageError = IgnorePageError,
                Log             = Log,
                Tracer          = Tracer,

                // 最多同时堆积数页
                BoundedCapacity = 4,
                TracerParent    = span,
            };

            var extracer = GetExtracter(table);

            // 临时关闭日志
            var old = Dal.Db.ShowSQL;

            Dal.Db.ShowSQL      = false;
            Dal.Session.ShowSQL = false;
            var total = 0;
            var sw    = Stopwatch.StartNew();

            try
            {
                // 表结构
                if (syncSchema)
                {
                    dal.SetTables(table);
                }

                foreach (var dt in extracer.Fetch())
                {
                    var row   = extracer.Row;
                    var count = dt.Rows.Count;
                    WriteLog("同步[{0}/{1}]数据 {2:n0} + {3:n0}", table.Name, Dal.ConnName, row, count);

                    // 进度报告、消费数据
                    OnProcess(table, row, dt, writeDb);

                    total += count;
                }

                // 通知写入完成
                writeDb.Stop(-1);
            }
            catch (Exception ex)
            {
                span?.SetError(ex, table);
                throw;
            }
            finally
            {
                Dal.Db.ShowSQL      = old;
                Dal.Session.ShowSQL = old;
            }

            sw.Stop();
            var ms = sw.Elapsed.TotalMilliseconds;

            WriteLog("同步[{0}/{1}]完成,共[{2:n0}]行,耗时{3:n0}ms,速度{4:n0}tps", table.Name, Dal.ConnName, total, ms, total * 1000L / ms);

            // 返回总行数
            return(total);
        }