在sqlite编程中多线程同时写时会出现异常,我写了个类来解决这个问题。

思路很简单,就是在开始写操作时,记下写操作的托管线程id,表示目前有线程正在做写操作;其他线程来写时,需要先检测是否有进程正在做写操作,如果有就需要等待,等待到某一个配置的超时时间时,会抛出异常终止等待;如果没有则直接放行,此线程可以获得写锁。最后写操作执行完毕时需要释放锁。

下面是具体的代码:

SQLiteWriteLock

/// <summary>

/// 用于在多线程访问sqlite时防止同步写导致锁文件

///

/// 使用方法:

/// using (SQLiteWriteLock sqliteLock = new SQLiteWriteLock(SQLite链接字符串))

/// {

///     //sqlite 写操作代码

/// }

///

/// 可以通过在配置文件appSettings节中添加设置 SQLiteWriteLockTimeout 的value值控制锁等待的超时时间,该值必须为正整数数字,单位为毫秒,

/// 默认的超时时间是1000ms

/// </summary>

public sealed class SQLiteWriteLock : IDisposable

{

#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 = ConfigurationManager.AppSettings["SQLiteWriteLockTimeout"];

if (!string.IsNullOrEmpty(configValule))

            {

return int.Parse(configValule);

            }

return 1000;

        }

    }

#endregion

private readonly string _connString;

//隐藏无参构造函数

private SQLiteWriteLock() { }

public SQLiteWriteLock(string connString)

    {

        _connString = connString;

        AcquireWriteLock();

    }

#region 私有方法

private void AcquireWriteLock()

    {

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 (_dbThreadIdDict.ContainsKey(_connString))

            {

                _dbThreadIdDict.Remove(_connString);

            }

        }

    }

#endregion

#region IDisposable 成员

public void Dispose()

    {

        ReleaseWriteLock();

    }

#endregion

}

希望此文有用。

SQLite多线程写锁文件解决方案的更多相关文章

  1. SQLite数据库在多线程写锁文件的解决办法

    参考了很多SQLITE数据库多线程的解决办法 我自己写了一个SQLITEHELPER 来解决这个问题 希望大家多多指教 调用的时候  SQLLiteDBHelper _SQLLiteDBHelper ...

  2. (原创)android Sqlite多线程访问异常解决方案

    在开发Android的程序的时候sqlite数据库是经常用到的:在多线程访问数据库的时候会出现这样的异常:java.lang.IllegalStateException: Cannot perform ...

  3. Sqlite多线程相关整理

    Sqlite多线程相关整理 Sqlite With MultiThreads 什么是线程安全? 当多个线程访问某个方法时,不管你通过怎样的调用方式.或者说这些线程如何交替地执行,我们在主程序中不需要去 ...

  4. JAVA多线程读写文件范例

    在写之前先声明,本文是基于之前在博客园网站上检索到的一份JAVA多线程读写文件的示例,我在写自己的程序时是在那位作者写的基础上做了改良,但已不记得原文的地址.如果有知情者,烦请帖出地址,我在此文上加入 ...

  5. SQLite多线程下的并发操作

    标签: sqlite多线程数据库跨平台嵌入式class 2011-04-14 13:29 26939人阅读 评论(2) 收藏 举报 这两天一直在捣鼓SQLite数据库,基本的操作就不说了,比较简单,打 ...

  6. Atitit.android播放smb 网络邻居视频文件解决方案

    Atitit.android播放smb 网络邻居视频文件解决方案 Android4.4 1.1. Android4视频播放器不能直接地支持smb协议..子好先转换成个http流 1.2. ES文件浏览 ...

  7. CoreData和SQLite多线程访问时的线程安全

    关于CoreData和SQLite多线程访问时的线程安全问题 数据库读取操作一般都是多线程访问的.在对数据进行读取时,我们要保证其当前状态不能被修改,即读取时加锁,否则就会出现数据错误混乱.IOS中常 ...

  8. ueditor1.3.6jsp版在struts2应用中上传图片报"未找到上传文件"解决方案

    摘要: ueditor1.3.6jsp版在struts2应用中上传图片报"未找到上传文件"解决方案 在struts2应用中使用ueditor富文本编辑器上传图片或者附件时,即使配置 ...

  9. AccessRandomFile多线程下载文件

    写一个工具类 package com.pb.thread.demo; import java.io.File; import java.io.FileNotFoundException; import ...

随机推荐

  1. css,html命名规则

    css,html命名规则 页头: header 登录条: loginBar 标志: logo 侧栏: sideBar 广告: banner 导航: nav 子导航: subNav 菜单: menu 子 ...

  2. UVa 524 Prime Ring Problem【回溯】

    题意:给出n,把从1到n排成一个环,输出相邻两个数的和为素数的序列 照着紫书敲的, 大概就是这个地方需要注意下,初始化的时候a[0]=1,然后dfs(1),从第1个位置开始搜 #include< ...

  3. UVA 550 Multiplying by Rotation (简单递推)

    题意:有些数字是可以这样的:abcd*k=dabc,例如179487 * 4 = 717948,仅仅将尾数7移动到前面,其他都不用改变位置及大小.这里会给出3个数字b.d.k,分别代表b进制.尾数.第 ...

  4. 求强连通分量模板(tarjan算法)

    关于如何求强连通分量的知识请戳 https://www.byvoid.com/blog/scc-tarjan/ void DFS(int x) { dfn[x]=lowlink[x]=++dfn_cl ...

  5. 【Unity3D】生成工程报错解决—UnityEditor.HostView:OnGUI() Error building Player: Couldn't build player because of unsupported data on target platform.

    错误 错误1:An asset is marked as dont save, but is included in the build: unityEditor.HostView:OnGUI() 错 ...

  6. HTML5实现扫描识别二维码/生成二维码

    扫描识别二维码 思路: 1. 操作摄像头,获取图片.HTML5 WEBRTC的navigator.getUserMedia方法去实时获取摄像头资源.  2. 利用canvas使用相关算法分析图片识别图 ...

  7. java多线程学习笔记——简单

    进程:程序(任务)的执行过程——动态性. 持有资源(共享内存,共享文件)和线程. 线程:线程是系统中最小的执行单元,统一进程中有多个线程,线程共享进程的资源. 线程交互:互斥与同步. 注意:多线程是异 ...

  8. IOS 时间 日历 处理集合

    1.获得当前时间 从1970开始的秒数 NSTimeInterval time = [[NSDate date[ timeIntervalSince1970]]; NSString * str = [ ...

  9. (转)我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  10. 各个城市优步uber注册司机官网地址汇总

    uber城市 开通uber城市 开通优步城市 哪些城市开通了uber   哪些城市开通了优步 分类: uber专车资讯 作为专车模式的创立者,Uber公司很早就进入了中国区域.优步在中国市场也是胸怀大 ...