加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-13 00:19:16 所属栏目:百科 来源:网络整理
导读:在sqlite编程中多线程同时写时会出现异常,我写了个类来解决这个问题。 思路很简单,就是在开始写操作时,记下写操作的托管线程id,表示目前有线程正在做写操作;其他线程来写时,需要先检测是否有进程正在做写操作,如果有就需要等待,等待到某一个配置的超

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

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

下面是具体的代码:

///<summary>
///用于在多线程访问sqlite时防止同步写导致锁文件
///
///使用方法:
///using(SQLiteWriteLocksqliteLock=newSQLiteWriteLock(SQLite链接字符串))
///{
/////sqlite写操作代码
///}
///
///可以通过在配置文件appSettings节中添加设置SQLiteWriteLockTimeout的value值控制锁等待的超时时间,该值必须为正整数数字,单位为毫秒,
///默认的超时时间是1000ms
///</summary>
publicsealedclassSQLiteWriteLock:IDisposable
{
#region静态字段和属性
constshortWAIT_TIME=5;
staticreadonlyobjectlocker=newobject();
staticDictionary<string,int>_dbThreadIdDict=newDictionary<string,int>();

///<summary>
///获得写操作的超时时间,单位为毫秒,可以通过配置文件appSettings节中添加设置SQLiteWriteLockTimeout的value值控制锁等待的超时时间,该值必须为正整数数字,单位为毫秒
///默认的超时时间是1000ms
///</summary>
publicstaticintSQLiteWriteLockTimeout
{
get
{
stringconfigValule=ConfigurationManager.AppSettings["SQLiteWriteLockTimeout"];
if(!string.IsNullOrEmpty(configValule))
{
returnint.Parse(configValule);
}
return1000;
}
}
#endregion

privatereadonlystring_connString;

//隐藏无参构造函数
privateSQLiteWriteLock(){}

publicSQLiteWriteLock(stringconnString)
{
_connString
=connString;
AcquireWriteLock();
}

#region私有方法

privatevoidAcquireWriteLock()
{
intthreadId=Thread.CurrentThread.ManagedThreadId;

intwaitTimes=0;
while(_dbThreadIdDict.ContainsKey(_connString)&&_dbThreadIdDict[_connString]!=threadId)
{
Thread.Sleep(WAIT_TIME);
waitTimes
+=WAIT_TIME;
#ifDEBUG
Console.WriteLine(_connString
+"waitfor"+waitTimes+"ms");
#endif
if(waitTimes>SQLiteWriteLockTimeout)
{
thrownewTimeoutException("SQLite等待写操作超时");
}
}

lock(locker)
{
if(!_dbThreadIdDict.ContainsKey(_connString))
_dbThreadIdDict.Add(_connString,threadId);
}
}

privatevoidReleaseWriteLock()
{
lock(locker)
{
if(_dbThreadIdDict.ContainsKey(_connString))
{
_dbThreadIdDict.Remove(_connString);
}
}
}

#endregion

#regionIDisposable成员

publicvoidDispose()
{
ReleaseWriteLock();
}

#endregion

}

请尊重作者的劳动,转载请保留链接玉开的技术博客

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读