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,许可[* ...
随机推荐
- winform学习笔记02
Hashtable 数据遍历的几种方式 ---Hashtable 在集合中称为键值对,它的每一个元素的类型是 DictionaryEntry,由于Hashtable对象的键和值都是Object类型,决 ...
- windows本地script脚本恶意代码分析(带注释)
//经过样本分析和抓取,该恶意程序是款下载者木马. //不懂的可以百度百科. http://baike.baidu.com/link?url=0dNqFM8QIjEQhD71ofElH0wHGktIQ ...
- IOS Core Animation Advanced Techniques的学习笔记(三)
第四章:Visual Effects Rounded Corners 例子4.1 cornerRadius 源码在这里下载:http://www.informit.com/title/978013 ...
- HDU 4951 Multiplication table(2014 Multi-University Training Contest 8)
思路 如果进制为p 那么当x<p时 (p-1)*(p-x)=(p-(x+1)) *p +x 因为x<p 所以没有进位 所以高位上的数字为 p-(x+1). 根 ...
- Android中ActionBar的使用
简介 从Android3.0开始(targetSdkVersion或者minSdkVersion为11或者更高),ActionBar被包括在了所有主题为Theme.holo(或者子类)的主题当中. 使 ...
- Eclipse中的一些快捷键的使用
Eclipse是一款强大的编程工具,在使用的过程中,若能够有效的使用其快捷键,效率会得到很大的提升,下面是一些常用的eclipse快捷键,可谓是键键精彩. 1.成单词:Alt+/ 2 重构之重命名:S ...
- as3 代码加解密
private var loader:URLLoader; ... private function init():void { loader = new URLLoader; req=URLRequ ...
- 006-Map、Tuple、Zip实战解析
006-Map.Tuple.Zip实战解析 实战代码 Map实战 本身是映射,映射关系在实际中应用非常广泛,比如:配置信息都是Key-Value形式 键值对不存在下边关系 是一个immutable(不 ...
- Large Margin DAGs for Multiclass Classification
Abstract We present a new learning architecture: the Decision Directed Acyclic Graph (DDAG), which i ...
- Android 中dp和px
dp是虚拟像素,在不同的像素密度的设备上会自动适配,比如: 在320x480分辨率,像素密度为160,1dp=1px 在480x800分辨率,像素密度为240,1dp=1.5px 计算公式: 1dp* ...