在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. POJ 3687 Labeling Balls【拓扑排序 优先队列】

    题意:给出n个人,m个轻重关系,求满足给出的轻重关系的并且满足编号小的尽量在前面的序列 因为输入的是a比b重,但是我们要找的是更轻的,所以需要逆向建图 逆向建图参看的这一篇http://blog.cs ...

  2. hdu 4691 Front compression

    暴力水过,剪一下枝= =果断是数据水了 #include<cstdio> #include<cstring> #include<algorithm> #define ...

  3. I.MX6 开启 1000Mb/s interface

    /*********************************************************************** * I.MX6 开启 1000Mb/s interfa ...

  4. HDU 2544 最短路 (最短路,spfa)

    题意:中文题目 思路:spfa+SLF优化.关于SPFA的详情请戳我 #include <bits/stdc++.h> using namespace std; , INF=0x7f7f7 ...

  5. 函数与关系实例,函数运算与SQL,试验与关系元组

    函数是一个集合,它的每个元素都是二元组或多元组.例如 f = { (x, y) | x∈R & y∈R & y = 2x } ,g = { (x, y, z) | (x, y, z)∈ ...

  6. context.Response.End()的用法和本质

    using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Web_C ...

  7. JS 代码编一个倒时器

    有时候在生活中,你需要一个JavaScript倒计时时钟,而不是一个末日装置设备.不管你是否有一次约会,销售.促销.或者游戏,你可以受益于使用原生JavaScript构建一个时钟,而不是拿到一个现成的 ...

  8. POJ 3233 Matrix Power Serie

    题意:给一个n×n的矩阵A,求S = A + A2 + A3 + … + Ak. 解法:从式子中可得递推式S(n) = S(n - 1) + An,An = An-1×A,可得矩阵递推式 [S(n), ...

  9. Oracle数据库表结构导出

    1. 在PL/SQL中找到"工具--导出用户对象"菜单.点击运行.

  10. 如何进行Monkey Test

    如何进行Monkey Test   目录 一 简介 二 测试准备 三 基本命令格式 四 测试Log获取 五 Monkey命令参数介绍 六 保存monkey log以及手机log到sdcard(新增) ...