在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. AngularJS promise()

    实例说明一 <!DOCTYPE html> <html ng-app="my-app"> <head> <meta charset=&qu ...

  2. 最简单的视音频播放示例7:SDL2播放RGB/YUV

    本文记录SDL播放视频的技术.在这里使用的版本是SDL2.实际上SDL本身并不提供视音频播放的功能,它只是封装了视音频播放的底层API.在Windows平台下,SDL封装了Direct3D这类的API ...

  3. liux之sed用法

    sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作,下面先了解一下sed的用法sed命令行格式为:         sed ...

  4. 【大数取模】HDOJ-1134、CODEUP-1086

    1086: 大数取模   题目描述 现给你两个正整数A和B,请你计算A mod B.为了使问题简单,保证B小于100000. 输入 输入包含多组测试数据.每行输入包含两个正整数A和B.A的长度不超过1 ...

  5. Delphi ORD

    //Char 类型与其编码值的转换:varb: Byte;c: Char;beginb := Ord('A');   {返回: 65}b := Ord(#65);   {返回: 65}b := Ord ...

  6. Linux下利用ioctl函数获取网卡信息

    linux下的ioctl函数原型如下: #include <sys/ioctl.h> int ioctl(int handle, int cmd, [int *argc, int argv ...

  7. HTTP协议学习笔记-2

    HTTP报文 HTTP报文分为请求报文和响应报文(requeset and response) 请求报文的格式: <method>  <request -URL> <ve ...

  8. Extjs Ext.onReady的用法

    最近在学习Extjs,当然首先学习的肯定是从官网下载下来的example. 从学习上而言对于Extjs,我个人认同的是李林峰老师所言先从视图开始,搞一些所见即所得的东西. 废话有点多,对于Extjs而 ...

  9. PHP 实现下载文件的方法

    方法一: header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); ...

  10. 【原】Storm Local模式和生产环境中Topology运行配置

    Storm入门教程 1. Storm基础 Storm Storm主要特点 Storm基本概念 Storm调度器 Storm配置 Guaranteeing Message Processing(消息处理 ...