使用事务操做SQLite数据批量插入,提升数据批量写入速度,源码讲解

SQLite数据库做为通常单机版软件的数据库,是很是优秀的,我目前单机版的软件产品线基本上所有替换Access做为优选的数据库了,在开发过程当中,有时候须要批量写入数据的状况,发现传统的插入数据模式很是慢,几千条数据的写入或者更新可能须要好几分钟时间,而SqlServer则相同的操做可能几秒便可,有无更好的方法来提升它的响应速度呢?答案是有的,就是采用事务提交,默认SQLite的数据库插入操做,若是没有采用事务的话,它每次写入提交,就会触发一次事务操做,而这样几千条的数据,就会触发几千个事务的操做,这就是时间耗费的根源。本文经过详细代码介绍如何使用事务来提升整个批量插入数据的速度,并以实际的Winform开发框架中的字典管理模块的批量插入功能来进行介绍,经过先后速度的对比,使得事务操做提升响应速度更有说服力。数据库

因为一些项目须要,字典管理模块须要批量录入数据,所以改善了个人《Winform开发框架》中的字典管理模块,在字典管理模块增长一个批量添加的功能,以下所示。框架

对一些诊断的数据录入,通常状况下均可能是几千条的数据,还有可能更多的一些分类字典,那么若是每次都须要等待几分钟或者几十分钟,那么这样的响应体验确定不好。函数

为了提升响应速度,我这里使用了事务操做,整个事务操做是基于EnterpriseLibray类库的数据库操做,因为我已经在框架的基类中作了封装,所以咱们这里看到整个处理过程便可。测试

其中MyRegion里面的代码就是遍历每行的数据,构造数据字典对象和排序号,而后调用InsertDictData函数进行数据的录入。其中InsertDictData函数的代码是this

        /// <summary>
        /// 使用事务参数,插入数据,最后统一提交事务处理
        /// </summary>
        /// <param name="dictData">字典数据</param>
        /// <param name="seq">排序</param>
        /// <param name="trans">事务对象</param>
        private void InsertDictData(string dictData, string seq, DbTransaction trans)
        {
            if (!string.IsNullOrWhiteSpace(dictData))
            {
                DictDataInfo info = new DictDataInfo();
                info.Editor = LoginID;
                info.LastUpdated = DateTime.Now;
                info.DictType_ID = this.txtDictType.Tag.ToString();
                info.Name = dictData.Trim();
                info.Value = dictData.Trim();
                info.Remark = this.txtNote.Text.Trim();
                info.Seq = seq;

                bool succeed = BLLFactory<DictData>.Instance.Insert(info, trans);
            }
        }

整个插入功能按钮的处理所有代码以下所示。spa

        private void btnOK_Click(object sender, EventArgs e)
        {
            string[] arrayItems = this.txtDictData.Lines;
            int intSeq = -1;
            int seqLength = 3;
            string strSeq = this.txtSeq.Text.Trim();
            if (int.TryParse(strSeq, out intSeq))
            {
                seqLength = strSeq.Length;
            }

            if (arrayItems != null && arrayItems.Length > 0)
            {
                DbTransaction trans = BLLFactory<DictData>.Instance.CreateTransaction();
                if (trans != null)
                {
                    try
                    {
                        #region MyRegion
                        foreach (string strItem in arrayItems)
                        {
                            if (this.radSplit.Checked)
                            {
                                if (!string.IsNullOrWhiteSpace(strItem))
                                {
                                    string[] dataItems = strItem.Split(new char[] { ',', '', ';', '', '/', '' });
                                    foreach (string dictData in dataItems)
                                    {
                                        #region 保存数据
                                        string seq = "";
                                        if (intSeq > 0)
                                        {
                                            seq = (intSeq++).ToString().PadLeft(seqLength, '0');
                                        }
                                        else
                                        {
                                            seq = string.Format("{0}{1}", strSeq, intSeq++);
                                        }

                                        InsertDictData(dictData, seq, trans); #endregion
                                    }
                                }
                            }
                            else
                            {
                                #region 保存数据
                                if (!string.IsNullOrWhiteSpace(strItem))
                                {
                                    string seq = "";
                                    if (intSeq > 0)
                                    {
                                        seq = (intSeq++).ToString().PadLeft(seqLength, '0');
                                    }
                                    else
                                    {
                                        seq = string.Format("{0}{1}", strSeq, intSeq++);
                                    }

                                    InsertDictData(strItem, seq, trans);
                                }
                                #endregion
                            }
                        }
                        #endregion

                        trans.Commit();
                        ProcessDataSaved(this.btnOK, new EventArgs());
                        MessageDxUtil.ShowTips("保存成功");
                        this.DialogResult = DialogResult.OK;
                    }
                    catch (Exception ex)
                    {
                        trans.Rollback();
                        LogTextHelper.Error(ex);
                        MessageDxUtil.ShowError(ex.Message);
                    }
                }
            }
        }

上面的批量插入,通过先后的测试,2千条数据批量插入SQLite数据库,须要大概3~4分钟左右,若是采用了事务操做,则在1~2秒内写入完成,速度提升不知道多少倍。若是是操做数据比较多的,强烈建议使用事务进行操做,能够给客户很好的体验效果。code

若是嫌上面的代码复杂,能够看下面的讲解代码可能就明白了orm

        using (DbTransaction dbTrans = conn.BeginTransaction())
        {
            using (DbCommand cmd = conn.CreateCommand())
            {
                cmd.CommandText = "INSERT INTO MyTable(MyValue) VALUES(?)";
                DbParameter Field1 = cmd.CreateParameter();
                cmd.Parameters.Add(Field1);
                for (int n = 0; n < 100000; n++)
                {
                    Field1.Value = n + 100000;
                    cmd.ExecuteNonQuery();
                }
            }
        }

上面是一种比较简单原始的事务操做,若是批量插入数据,一样可以起到同样的效果。对象

相关文章
相关标签/搜索