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,许可[* ...
随机推荐
- TypeError: window.open is not a function
想必大家现在都已经到家了,而苦逼的我还要坐在办公室混拿微薄的工资,技不如人,平常不努力给自己充电,年终一毛钱都没多给.不说这扫兴的话题了,在这给同样在苦逼坚守岗位的同志们节日的问候,新的一年,好运连连 ...
- SQLSERVER和ORACLE系统表获取表名 列名以及列的注释
在工作中从数据库取的数据要导出来,但是发现导出的EXCEL中列名都是字段名(英文),为此搜集资料怎么把字段名变为中文名称,而发现ORACLE和SQLSERVER(用的SQLSERVER2008R2)又 ...
- 怎么把Windows主机上的目录共享到Ubuntu上
使用Oracle VM VirtualBox在Windows主机上创建了一台Ubuntu虚拟机,怎么把宿主机上的目录共享到Ubuntu上,可使用以下方法: eg.把Windows主机上D盘里的test ...
- ionic实现上拉到底内容提示
<!--html代码--> <ion-content has-bouncing = true on-drag-up="scrollDragUp()"> &l ...
- JavaScript 继承
许多OO语言都支持两种继承方式,接口继承和实现继承.接口继承只继承方法签名,而实现继承则继承实际的方法.由于在ECMAScript中,函数没有签名,无法实现接口继承,只支持实现继承,而且其实现继承主要 ...
- Dapper 数据操作框架
数据操作DapperFrom NuGet:Install-Package DapperorInstall-Package Dapper.StrongName微型ORM:PetaPoco获得PetaPo ...
- RBAC类的方法
rbac类的 方法 authenticate($map,$model='')方法 传入查询用户的条件和用户表的MODEL 返回数组包含用户的信息 saveAccessList($authId=null ...
- c/c++程序员必须要掌握开源项目
作为一个经验丰富的C/C++程序员, 肯定亲手写过各种功能的代码, 比如封装过数据库访问的类, 封装过网络通信的类,封装过日志操作的类, 封装过文件访问的类, 封装过UI界面库等, 也在实际的项目中应 ...
- CFD计算
47 求解器为flunet5/6在设置边界条件时,specify boundary types下的types中有三项关于interior,interface,internal设置,在什么情况下设置相应 ...
- SQLServer - 约束
一.约束的分类 在SQLServer中,有3种不同类型的约束. 1.实体约束 实体约束是关于行的,比如某一行出现的值就不允许出现在其他行,例如主键. 2.域约束 域约束是关于列的,对于所有行,某一列有 ...