`

SQLite多线程写锁文件解决方案

阅读更多

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

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

下面是具体的代码:
<!---->/// <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<stringint> _dbThreadIdDict = new Dictionary<stringint>();

    
/// <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
}

 

希望此文有用。

3
0
分享到:
评论

相关推荐

    QT中sqlite多线程操作4个注意问题

    本文将总结在Qt环境下进行SQLite多线程操作时遇到的四个关键问题及其解决方案。 #### 1. 多线程下的各个线程或定时器数据库驱动加载需独立进行 在多线程环境中,不同线程间共享资源会导致各种难以预料的问题。对于...

    多进程写sqlite互斥解决方案代码

    本文将详细探讨标题所提及的“多进程写SQLite互斥解决方案代码”,以及它如何处理多线程环境下的类似问题。 SQLite是一个轻量级、嵌入式的关系型数据库,广泛应用于各种桌面应用、移动应用甚至服务器端。然而,当多...

    深入Sqlite多线程入库的问题

    在多线程环境下,多个线程同时对SQLite数据库进行写入操作可能导致数据竞争、锁冲突和性能下降。SQLite通过使用页级锁定机制来支持多线程访问,这意味着当一个线程对数据库的某一页进行修改时,其他线程可能被阻止...

    sqlite3.30.1 数据库模块+支持库(彻底解决多线程死锁问题)-易语言

    SQLite3.30.1是SQLite数据库引擎的一个特定版本,专为易语言用户设计,旨在提供一个高效且可靠的多线程数据库解决方案,特别是在处理可能引发死锁问题的并发操作时。SQLite是一个开源、轻量级的嵌入式数据库,常用于...

    断点多线程下载.

    Android提供了多种多线程解决方案,如AsyncTask、Handler、Looper、Thread和ThreadPoolExecutor等。在这个项目中,可能使用了AsyncTask或者自定义的线程池来实现多线程下载。 其次,断点续传是下载过程中的一种优化...

    sqlite3源码及编译好的文件

    5. **锁机制**:为了实现多线程访问,SQLite3使用了行级锁定和页级锁定策略,以减少冲突并提高并发性能。 6. **错误处理和日志记录**:SQLite3有丰富的错误处理机制,包括错误码、错误消息以及可配置的日志记录,有...

    SQLite的.dll和.so文件及相关问题文档

    4. **多线程问题**:SQLite默认不支持多线程并发访问,所以在多线程环境下使用SQLite需要注意同步管理。可以使用SQLite的WAL模式(Write-Ahead Logging)来提高并发性能。 5. **数据迁移和升级**:随着项目的迭代,...

    SpringMVC+sqlitejdbc的jar集合

    - SQLite不支持多线程写入,所以在并发较高的场景下可能不是最佳选择。 - 虽然SQLiteJDBC能简化数据库操作,但它的性能和功能可能不如大型数据库系统如MySQL或Oracle。 - 使用SpringMVC时,合理配置...

    sqlite 3070603 vs2010 工程文件

    3. **添加引用**:在解决方案资源管理器中,右键点击项目,选择“添加”-&gt;“现有项”,找到解压后的SQLite文件夹,选择所需的头文件(如sqlite3.h)和库文件(如sqlite3.lib)。如果你需要链接动态库(dll),也需要...

    C#多线程文件下载工具(访问restful形式接口)

    总的来说,这个C#多线程文件下载工具是一个综合性的解决方案,它涵盖了网络通信(通过HTTPClient访问REST API)、多线程下载以提高效率、本地数据存储(使用SQLite)以及文件压缩(使用ZipFile)。这样的工具对于...

    sqlite动态链接库

    - **并发访问**:虽然SQLite支持多线程,但在高并发环境下可能需要额外的锁策略来保证数据一致性和性能。 - **数据库版本管理**:升级SQLite库可能导致旧版应用程序无法识别新的数据库结构,因此需要谨慎处理版本...

    sqlite-tools-win32-x86-3360000.zip(sqllite安装包)

    SQLite常用于移动应用、嵌入式系统、Web应用、本地数据存储、测试环境等,尤其适合那些需要轻量级数据库解决方案且对实时性和数据完整性的要求不那么严格的情况。 6. 开发者支持: SQLite拥有活跃的社区和丰富的...

    sqlite开发文档全手册

    本开发文档全手册将深入探讨SQLite3的各个方面,包括基础操作、高级特性以及常见问题的解决方案。 1. SQLite3 API介绍 SQLite3 API提供了C语言接口,让开发者能够方便地在程序中集成数据库功能。关键函数包括`...

    sqlite+.net4.0

    同时,如果应用程序需要在多线程环境中运行,需要了解SQLite.NET版本是否支持线程安全操作,因为某些版本可能需要手动配置。 另外,当处理大量数据时,注意避免内存溢出。可以使用数据流或分批处理技术,减少一次性...

    sqlite3.dll

    总之,SQLite3是一个强大且灵活的数据库解决方案,尤其适合于不需要大型数据库系统的轻量级应用场景。其易于使用、高度兼容和良好的性能使得它成为许多开发者的选择。通过理解和熟练运用SQLite3.dll,开发者可以快速...

    sqlite指南的翻译版本讲解

    它不需要单独的服务器进程,并且能够被应用程序直接访问,这使得SQLite成为许多开发者的首选数据库解决方案。 本翻译版的"SQLite指南"旨在帮助读者深入理解SQLite的工作原理和使用方法,涵盖的内容包括但不限于以下...

    SQLITE64位(System.Data.SQLite.DLL).zip

    在并发环境下,SQLite支持多种隔离级别,如读未提交、读已提交、可重复读和序列化,这些特性使得SQLite适合于多线程和分布式应用。 总而言之,"SQLITE64位(System.Data.SQLite.DLL).zip"提供的是一个适用于64位...

    SQLite数据库案例完整解析

    它被广泛应用于移动设备、嵌入式系统以及桌面应用中,尤其在Android和iOS平台上,SQLite是默认的数据库解决方案。这篇“SQLite数据库案例完整解析”将深入探讨SQLite的核心概念、操作方式以及在实际应用中的实例。 ...

Global site tag (gtag.js) - Google Analytics