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<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
}
希望此文有用。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构