使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解
SQLite数据库作为一般单机版软件的数据库,是非常优秀的,我目前单机版的软件产品线基本上全部替换Access作为优选的数据库了,在开发过程中,有时候需要批量写入数据的情况,发现传统的插入数据模式非常慢,几千条数据的写入或者更新可能需要好几分钟时间,而SqlServer则相同的操作可能几秒即可,有无更好的方法来提高它的响应速度呢?答案是有的,就是采用事务提交,默认SQLite的数据库插入操作,如果没有采用事务的话,它每次写入提交,就会触发一次事务操作,而这样几千条的数据,就会触发几千个事务的操作,这就是时间耗费的根源。本文通过详细代码介绍如何使用事务来提高整个批量插入数据的速度,并以实际的Winform开发框架中的字典管理模块的批量插入功能来进行介绍,通过前后速度的对比,使得事务操作提高响应速度更有说服力。
由于一些项目需要,字典管理模块需要批量录入数据,因此改善了我的《Winform开发框架》中的字典管理模块,在字典管理模块增加一个批量添加的功能,如下所示。

对一些诊断的数据录入,一般情况下都可能是几千条的数据,还有可能更多的一些分类字典,那么如果每次都需要等待几分钟或者几十分钟,那么这样的响应体验肯定很差。
为了提高响应速度,我这里使用了事务操作,整个事务操作是基于EnterpriseLibray类库的数据库操作,由于我已经在框架的基类中做了封装,因此我们这里看到整个处理过程即可。

其中MyRegion里面的代码就是遍历每行的数据,构造数据字典对象和排序号,然后调用InsertDictData函数进行数据的录入。其中InsertDictData函数的代码是
/// <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);
}
}
整个插入功能按钮的处理全部代码如下所示。
private void btnOK_Click(object sender, EventArgs e)
{
string[] arrayItems = this.txtDictData.Lines;
int intSeq = -;
int seqLength = ;
string strSeq = this.txtSeq.Text.Trim();
if (int.TryParse(strSeq, out intSeq))
{
seqLength = strSeq.Length;
} if (arrayItems != null && arrayItems.Length > )
{
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 > )
{
seq = (intSeq++).ToString().PadLeft(seqLength, '');
}
else
{
seq = string.Format("{0}{1}", strSeq, intSeq++);
} InsertDictData(dictData, seq, trans);
#endregion
}
}
}
else
{
#region 保存数据
if (!string.IsNullOrWhiteSpace(strItem))
{
string seq = "";
if (intSeq > )
{
seq = (intSeq++).ToString().PadLeft(seqLength, '');
}
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秒内写入完成,速度提高不知道多少倍。如果是操作数据比较多的,强烈建议使用事务进行操作,可以给客户很好的体验效果。
如果嫌上面的代码复杂,可以看下面的讲解代码可能就明白了
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 = ; n < ; n++)
{
Field1.Value = n + ;
cmd.ExecuteNonQuery();
}
}
}
上面是一种比较简单原始的事务操作,如果批量插入数据,同样能够起到一样的效果。
使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解的更多相关文章
- SQL-35 对于表actor批量插入如下数据,如果数据已经存在,请忽略,不使用replace操作
题目描述 对于表actor批量插入如下数据,如果数据已经存在,请忽略,不使用replace操作CREATE TABLE IF NOT EXISTS actor (actor_id smallint(5 ...
- SQL-34 对于表actor批量插入如下数据
题目描述 对于表actor批量插入如下数据CREATE TABLE IF NOT EXISTS actor (actor_id smallint(5) NOT NULL PRIMARY KEY,fir ...
- .net使用SqlBulkCopy类操作DataTable批量插入数据库数据,然后分页查询坑
在使用SqlBulkCopy类操作DataTable批量插入数据,这种操作插入数据的效率很高,就会导致每一条数据在保存的时间基本一样,在我们分页查询添加的数据是,使用数据的添加时间来排序就会出现每页的 ...
- 在pycharm中批量插入表数据、分页原理、cookie和session介绍、django操作cookie
昨日内容回顾 ajax发送json格式数据 ''' 1. urlencoded 2. form-data 3. json ''' 1. ajax $.ajax({ data: JSON.stringi ...
- MySQL批量插入大量数据方法
在MySQL数据库中,如果要插入上百万级的记录,用普通的insert into来操作非常不现实,速度慢人力成本高,推荐使用Load Data或存储过程来导入数据,我总结了一些方法分享如下,主要基于My ...
- ADO.NET 新特性之SqlBulkCopy(批量插入大量数据)
转自:http://blog.csdn.net/huaer1011/article/details/2312361 在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,还 ...
- JDBC批量插入blob数据
图片从接口读取后是base64的字符串,所以转成byte数组进行保存. 我们一般保存数据的话,都是基本数据,对于这些图片数据大部分会将图片保存成Blob,Clob等. Blob存储的是二进制对象数据( ...
- .Net批量插入数据到SQLServer数据库,System.Data.SqlClient.SqlBulkCopy类批量插入大数据到数据库
批量的的数据导入数据库中,尽量少的访问数据库,高性能的对数据库进行存储. 采用SqlBulkCopy来处理存储数据.SqlBulkCopy存储大批量的数据非常的高效,将内存中的数据表直接的一次性的存储 ...
- oracle 快速批量插入复杂数据的内容
最近迷上一种批量插入的方法,一句sql解决,将需要插入的数据用with as 的方式查出来,不管多么复杂的sql,都可以用临时表的方式查出来,然后直接插入,这样代码更加清晰 流程也简单 insert ...
随机推荐
- gradle介绍
Gradle是什么? https://gradle.org/whygradle-build-automation/ 自动化编译的工具,可编程,适合各种语言,管理各种依赖,高效,提供分析报告. 我个人觉 ...
- C#接口的使用场合,接口应用
当一个项目不断的扩大的时候,会面临的问题是不断的有以下情况: 1.以前编写程序的人离职了,新来的程序员看不懂以前的程序,或者觉得以前的程序部够好,但又不希望删除: 2.当实现第三方接口时,如:读写IC ...
- LINQ TO ENTITY 根据Birthday获取Age
from emp in EmployeeInfo let years = EntityFunctions.DiffYears(emp.Birthday.Value,DateTime.Now) let ...
- oracle 中触发器增加存储过程commit问题
触发器无需commit也不能写commit触发器和触发它的DML是同一个事务DML提交了,触发器的操作也提交了,要不就一起回滚了 当然,如果你一定要在触发器里写COMMIT那就用自治事务相当于一个事务 ...
- Jenkins 安装或更新插件失败
试试这个插件网址是否可以在网页中打开 http://mirror.xmission.com/jenkins/updates/current/update-center.json 如可以,把这个网址 ...
- php 生成 Json
php 生成 Json 部分 <?php $arr_result = array(); //返回值 $arr_result['result'] = '0'; $arr_result['calle ...
- eclipse新建一个Android项目,就会报错android.support.v7.app.ActionBarActivity
解决方法: 今天被这个问题折腾了一下,最后终于找到了解决办法. 产生这个问题,是因为你升级了ADT到version 22,但是还需要升级SDK Tools,Platform Tools,Build T ...
- Python Base HTTP Server
import BaseHTTPServer import cgi, random, sys MESSAGES = [ "That's as maybe, it's still a frog. ...
- thinkphp的伪静态化
1. 设置默认的控制器和模块 // 绑定访问Admin模块 define('BIND_MODULE','Home'); // 绑定访问Index控制器 define('BIND_CONTROLLER' ...
- sizeof and strlen整理
sizeof 定义 计算对象或类型所占用的字节数(byte) 记住是字节数,而不是个数 语法 sizeof(对象) int i; sizeof(i); sizeof(类型) sizeof(int); ...