SQLite数据库在多线程写锁文件的解决办法
参考了很多SQLITE数据库多线程的解决办法 我自己写了一个SQLITEHELPER 来解决这个问题
希望大家多多指教
调用的时候
SQLLiteDBHelper _SQLLiteDBHelper = new SQLLiteDBHelper();
_SQLLiteDBHelper.Dispose();
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SQLite;
using System.Threading; namespace DAL
{
public class SQLLiteDBHelper : IDisposable
{
public static string Connectionstring = "";
/// <summary>
/// 获得连接对象
/// </summary>
/// <returns></returns>
public SQLiteConnection GetSQLiteConnection()
{
//return new SQLiteConnection(Connectionstring);
SQLiteConnection conn = new SQLiteConnection();
try
{ conn.ConnectionString = Connectionstring;
if (conn.State.Equals(ConnectionState.Closed))
{
conn.DefaultTimeout = 5000;
conn.Open(); } }
catch (Exception ee)
{ //OAFile.ErrorLog(OAFile.GetCurrUrl(), "链接字符串错误,请检查,详细错误:" + ee.Message);
}
return conn;
} /// <summary>
/// COMMAND初始化
/// </summary>
/// <param name="cmd"></param>
/// <param name="conn"></param>
/// <param name="cmdText"></param>
/// <param name="p"></param>
private void PrepareCommand(SQLiteCommand cmd, SQLiteConnection conn, string cmdText, params object[] p)
{
try
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Parameters.Clear();
cmd.Connection = conn;
cmd.CommandText = cmdText;
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 30;
if (p != null)
{
foreach (object parm in p)
cmd.Parameters.Add(parm);
}
}
catch (Exception)
{ } } /// <summary>
/// 批量执行带参数的SQL语句 事务 并返回执行结果
/// </summary>
/// <param name="SQLStringList"></param>
/// <param name="PramsList"></param>
/// <returns></returns>
public string ExecuteSqlTran(List<string> SQLStringList, List<SQLiteParameter[]> PramsList)
{
AcquireWriteLock();
string result = "执行成功";
using (SQLiteConnection conn = GetSQLiteConnection())
{
using (SQLiteCommand cmd = new SQLiteCommand())
{
try
{
cmd.Connection = conn;
SQLiteTransaction tx = conn.BeginTransaction();
cmd.Transaction = tx;
try
{
for (int i = 0; i < SQLStringList.Count; i++)
{
if (SQLStringList[i].Trim().Length > 1)
{
PrepareCommand(cmd, conn, SQLStringList[i].Trim(), PramsList[i]);
cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
}
tx.Commit();
}
catch (Exception ex)
{
tx.Rollback();
result = ex.Message.Trim();
}
}
catch (Exception)
{ result = "lock";
} }
}
return result;
} /// <summary>
/// 批量执行带参数的SQL语句 事务 并返回执行结果
/// </summary>
/// <param name="SQLStringList"></param>
/// <param name="PramsList"></param>
/// <returns></returns>
public string ExecuteSqlTran(List<string> SQLStringList)
{
AcquireWriteLock();
string result = "执行成功";
using (SQLiteConnection conn = GetSQLiteConnection())
{
using (SQLiteCommand cmd = new SQLiteCommand())
{
cmd.Connection = conn;
SQLiteTransaction tx = conn.BeginTransaction();
cmd.Transaction = tx;
try
{
for (int i = 0; i < SQLStringList.Count; i++)
{
if (SQLStringList[i].Trim().Length > 1)
{
PrepareCommandNoParameters(cmd, conn, SQLStringList[i].Trim());
cmd.ExecuteNonQuery();
// cmd.Parameters.Clear();
}
}
tx.Commit();
}
catch (Exception ex)
{
if (conn.State!=ConnectionState.Closed)
{
tx.Rollback();
} result = ex.Message.Trim();
}
}
}
return result;
} /// <summary>
/// COMMAND初始化
/// </summary>
/// <param name="cmd"></param>
/// <param name="conn"></param>
/// <param name="cmdText"></param>
/// <param name="p"></param>
private void PrepareCommandNoParameters(SQLiteCommand cmd, SQLiteConnection conn, string cmdText)
{
try
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = 30;
}
catch (Exception)
{ }
} /// <summary>
/// 返回DataSet
/// </summary>
/// <param name="cmdText"></param>
/// <param name="p"></param>
/// <returns></returns>
public DataSet DS(string cmdText, params object[] p)
{
DataSet ds = new DataSet();
SQLiteCommand command = new SQLiteCommand();
using (SQLiteConnection connection = GetSQLiteConnection())
{
PrepareCommand(command, connection, cmdText, p);
SQLiteDataAdapter da = new SQLiteDataAdapter(command);
da.Fill(ds);
}
return ds;
} /// <summary>
/// 返回DataTable
/// </summary>
/// <param name="cmdText"></param>
/// <param name="p"></param>
/// <returns></returns>
public DataTable DT(string cmdText, params object[] p)
{
DataSet ds = new DataSet();
SQLiteCommand command = new SQLiteCommand();
using (SQLiteConnection connection = GetSQLiteConnection())
{
PrepareCommand(command, connection, cmdText, p);
SQLiteDataAdapter da = new SQLiteDataAdapter(command);
da.Fill(ds);
}
return ds.Tables[0];
} /// <summary>
/// 返回DataTable
/// </summary>
/// <param name="cmdText"></param>
/// <param name="p"></param>
/// <returns></returns>
public DataTable DT(string cmdText)
{
DataSet ds = new DataSet();
SQLiteCommand command = new SQLiteCommand();
using (SQLiteConnection connection = GetSQLiteConnection())
{
PrepareCommandNoParameters(command, connection, cmdText);
SQLiteDataAdapter da = new SQLiteDataAdapter(command);
da.Fill(ds);
}
return ds.Tables[0];
} /// <summary>
/// 返回执行数据的行数
/// </summary>
/// <param name="cmdText"></param>
/// <param name="p"></param>
/// <returns></returns>
public DataRow ExecuteDataRow(string cmdText, params object[] p)
{
DataSet ds = DS(cmdText, p);
if (ds != null && ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0)
return ds.Tables[0].Rows[0];
return null;
}
/// <summary>
/// 返回受影响的行数
/// </summary>
/// <param name="cmdText">a</param>
/// <param name="commandParameters">传入的参数</param>
/// <returns></returns>
public int ExecuteNonQuery(string cmdText, params object[] p)
{
AcquireWriteLock();
SQLiteCommand command = new SQLiteCommand();
using (SQLiteConnection connection = GetSQLiteConnection())
{
PrepareCommand(command, connection, cmdText, p);
return command.ExecuteNonQuery();
}
} /// <summary>
/// 返回受影响的行数
/// </summary>
/// <param name="cmdText">a</param>
/// <param name="commandParameters">传入的参数</param>
/// <returns></returns>
public int ExecuteNonQuery(string cmdText)
{
AcquireWriteLock();
SQLiteCommand command = new SQLiteCommand();
using (SQLiteConnection connection = GetSQLiteConnection())
{ PrepareCommandNoParameters(command, connection, cmdText);
return command.ExecuteNonQuery();
}
} /// <summary>
/// 返回SqlDataReader对象
/// </summary>
/// <param name="cmdText"></param>
/// <param name="commandParameters">传入的参数</param>
/// <returns></returns>
public SQLiteDataReader ExecuteReader(string cmdText, params object[] p)
{
SQLiteCommand command = new SQLiteCommand();
SQLiteConnection connection = GetSQLiteConnection();
try
{
PrepareCommand(command, connection, cmdText, p);
SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.CloseConnection);
return reader;
}
catch
{
connection.Close();
throw;
}
} /// <summary>
/// 返回结果集中的第一行第一列,忽略其他行或列
/// </summary>
/// <param name="cmdText"></param>
/// <param name="commandParameters">传入的参数</param>
/// <returns></returns>
public object ExecuteScalar(string cmdText, params object[] p)
{
SQLiteCommand cmd = new SQLiteCommand();
using (SQLiteConnection connection = GetSQLiteConnection())
{
PrepareCommand(cmd, connection, cmdText, p);
return cmd.ExecuteScalar();
}
} /// <summary>
/// 分页
/// </summary>
/// <param name="recordCount"></param>
/// <param name="pageIndex"></param>
/// <param name="pageSize"></param>
/// <param name="cmdText"></param>
/// <param name="countText"></param>
/// <param name="p"></param>
/// <returns></returns>
public DataSet ExecutePager(ref int recordCount, int pageIndex, int pageSize, string cmdText, string countText, params object[] p)
{
if (recordCount < 0)
recordCount = int.Parse(ExecuteScalar(countText, p).ToString());
DataSet ds = new DataSet();
SQLiteCommand command = new SQLiteCommand();
using (SQLiteConnection connection = GetSQLiteConnection())
{
PrepareCommand(command, connection, cmdText, p);
SQLiteDataAdapter da = new SQLiteDataAdapter(command);
da.Fill(ds, (pageIndex - 1) * pageSize, pageSize, "result");
}
return ds;
} #region 静态字段和属性
const short WAIT_TIME = 5;
static readonly object locker = new object();
static Dictionary<string, int> _dbThreadIdDict = new Dictionary<string, int>();
/// <summary>
/// 获得写操作的超时时间,单位为毫秒,可以通过配置文件appSettings节中添加设置 SQLiteWriteLockTimeout 的value值控制锁等待的超时时间,该值必须为正整数数字,单位为毫秒
/// 默认的超时时间是1000ms
/// </summary>
public static int SQLiteWriteLockTimeout
{
get
{
string configValule = "300000";
if (!string.IsNullOrEmpty(configValule))
{
return int.Parse(configValule);
}
return 1000;
}
}
#endregion private string _connString; public SQLLiteDBHelper()
{
} #region 私有方法 private void AcquireWriteLock()
{
if (Connectionstring=="")
{
return;
}
_connString = Connectionstring;
int threadId = Thread.CurrentThread.ManagedThreadId; int waitTimes = 0;
while (_dbThreadIdDict.ContainsKey(_connString) && _dbThreadIdDict[_connString] != threadId)
{
Thread.Sleep(WAIT_TIME);
waitTimes += WAIT_TIME;
#if DEBUG
Console.WriteLine(_connString + " wait for " + waitTimes + " ms");
#endif
if (waitTimes > SQLiteWriteLockTimeout)
{
//throw new TimeoutException("SQLite等待写操作超时");
}
} lock (locker)
{
if (!_dbThreadIdDict.ContainsKey(_connString))
_dbThreadIdDict.Add(_connString, threadId);
}
} private void ReleaseWriteLock()
{
lock (locker)
{
if (_connString!=null)
{
if (_dbThreadIdDict.ContainsKey(_connString))
{
_dbThreadIdDict.Remove(_connString);
}
} }
} #endregion #region IDisposable 成员 public void Dispose()
{
ReleaseWriteLock();
}
#endregion
}
}
SQLite数据库在多线程写锁文件的解决办法的更多相关文章
- sql server 数据库正在使用该文件的解决办法
今天在帮朋友还原数据库时遇到了一个问题.朋友用的是sql server 2008数据库,本身有一个数据库,他在修改程序的时候,想修改数据库的内容.但是又不想在原数据库中修改.想备份还原出一个数据库然后 ...
- 对SQLite数据库操作 操作db文件
sqlite数据库就是一个DB文件. 程序每操作一次数据库都要读一次 .DB 文件 . 这个文件就是这个SQLite数据库. 如果需要依赖包的可以联系我 工具类: package com.hot ...
- “只有DBA才能导入由其他DBA导出的文件”各种解决办法
“只有DBA才能导入由其他DBA导出的文件”各种解决办法 当oracle导入的时候出现“只有 DBA 才能导入由其他 DBA 导出的文件”的时候通常有以下几种解决办法! 1:常见的是直接grant ...
- MySQL安装过程net start mysql 启动失败 报“错误2,系统找不到文件”的解决办法
MySQL安装过程net start mysql 启动失败 报“错误2,系统找不到文件”的解决办法 错误2,系统找不到文件. 开始...运行... regedit 注册表项: HKEY_LOCAL_ ...
- ubuntu Linux 测试PHP却提示下载文件的解决办法
ubuntu Linux 测试PHP却提示下载文件的解决办法 一般这种情况都是在刚刚开始配置环境时出现的, 输入 sudo a2enmod php5 看提示如果出现“$ This module ...
- Ubuntu“无法解析或打开软件包的列表或是状态文件”的解决办法。_StarSasumi_新浪博客
Ubuntu"无法解析或打开软件包的列表或是状态文件"的解决办法. (2011-04-30 14:56:14) 转载▼ 标签: ubuntu apt 分类: Ubuntu/Linu ...
- mysql数据库死锁的产生原因及解决办法
这篇文章主要介绍了mysql数据库锁的产生原因及解决办法,需要的朋友可以参考下 数据库和操作系统一样,是一个多用户使用的共享资源.当多个用户并发地存取数据 时,在数据库中就会产生多个事务同时存取同 ...
- IOS7.1-7.1.1越狱后无法读取越狱文件的解决办法
IOS7.1-7.1.1越狱后无法读取越狱文件的解决办法 申明: 下面安装PP源的方法已经失效,请不用按照下面的方法操作. 更新最新的方法,在cydia中搜索源 apple fil ...
- Chrome不能在网易网盘中上传文件的解决办法
Chrome不能在网易网盘中上传文件的解决办法1. 安装 Adobe Flash Player PPAPI,设置flash插件 chrome://settings/content/flash,许可[* ...
随机推荐
- 利用ajax向jsp传输数据
ajax代码 var obtn=document.getElementsByTagName('input')[0]; obtn.onclick=function () { var xhr=null; ...
- 【图像处理】【SEED-VPM】7.ubuntu10.04下 TFTP,NFS 安装指南
Linux系统启动流程 程序开发调试的一般方法 1. TFTP下载内核+NFS网络文件系统.即内核和文件系统均不在板卡上.主要用于调试内核功能. 2. FLASH启动内核+NFS网络文件系统,即内核固 ...
- 调整ESX的VMFS磁盘格式的块大小,让单个虚拟磁盘支持更大容量
调整ESX的VMFS磁盘格式的块大小,让单个虚拟磁盘支持更大容量 前因:客户搭建了VMware ESX企业版的测试平台:有一天接到一个需求,是测试数据库的,需要一个300G的磁盘. 解决过程: 1.按 ...
- 第八篇.Bootstrap下拉菜单
给div一个class “dropdown”,将下拉菜单放在这个div里就可以显示bootstrap的下拉菜单. <div class="dropdown"> < ...
- extjs之apply
ext.apply(Ext.Form.VTypes,{}) {}里面的内容如下: { password:function (val.field) { if(field.initialPassField ...
- 通过js对cookie的使用手册
一般大多数人还是用引用JQuary API——jquery.cookie.js,来操作cookie.这是一种很不错的方式,我也支持这样的做法. 但是有时候我们只需要一种极为轻量级的代码来实现简单的功能 ...
- Android高效加载大图、多图解决方案,有效避免程序OOM
高效加载大图片 我们在编写Android程序的时候经常要用到许多图片,不同图片总是会有不同的形状.不同的大小,但在大多数情况下,这些图片都会大于我们程序所需要的大小.比如说系统图片库里展示的图片大都是 ...
- scala学习----柯里化
1.鸭子类型,走起来像鸭子,叫起来像鸭子,就是鸭子.函数中使用{ def close(): Unit }作为参数类型,因此任何含有此函数的类都可以作为参数传递.好处是不必使用继承特性. def wit ...
- 适合PHP学习者的学习路线 10个PHP优化技巧
适合PHP学习者的学习路线: (1) 熟悉HTML/CSS/JS..网页基本元素,完成阶段可自行制作简单的网页,对元素属性相对熟悉 (2) 理解动态语言的概念和运做机制,熟悉基本的PHP语法 (3) ...
- PreparedStatement
PreparedStatement > 它是Statement接口的子接口: >强大之处: 防SQL攻击: 提高代码的可读性.可维护性: 提高效率! l 学习PreparedStateme ...