微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

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

下面是具体的代码

·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
  1. ///<summary>
  2. ///用于在多线程访问sqlite时防止同步写导致锁文件
  3. ///
  4. ///使用方法
  5. ///using(sqliteWriteLocksqliteLock=newsqliteWriteLock(sqlite链接字符串))
  6. ///{
  7. /////sqlite写操作代码
  8. ///}
  9. ///
  10. ///可以通过在配置文件appSettings节中添加设置sqliteWriteLockTimeout的value值控制锁等待的超时时间,该值必须为正整数数字,单位为毫秒,
  11. ///认的超时时间是1000ms
  12. ///</summary>
  13. publicsealedclasssqliteWriteLock:Idisposable
  14. {
  15. #region静态字段和属性
  16. constshortWAIT_TIME=5;
  17. staticreadonlyobjectlocker=newobject();
  18. staticDictionary<string,int>_dbThreadIdDict=newDictionary<string,int>();
  19. ///<summary>
  20. ///获得写操作的超时时间,单位为毫秒,可以通过配置文件appSettings节中添加设置sqliteWriteLockTimeout的value值控制锁等待的超时时间,该值必须为正整数数字,单位为毫秒
  21. ///认的超时时间是1000ms
  22. ///</summary>
  23. publicstaticintsqliteWriteLockTimeout
  24. {
  25. get
  26. {
  27. stringconfigValule=ConfigurationManager.AppSettings["sqliteWriteLockTimeout"];
  28. if(!string.IsNullOrEmpty(configValule))
  29. {
  30. returnint.Parse(configValule);
  31. }
  32. return1000;
  33. }
  34. }
  35. #endregion
  36. privatereadonlystring_connString;
  37. //隐藏无参构造函数
  38. privatesqliteWriteLock(){}
  39. publicsqliteWriteLock(stringconnString)
  40. {
  41. _connString=connString;
  42. AcquireWriteLock();
  43. }
  44. #region私有方法
  45. privatevoidAcquireWriteLock()
  46. {
  47. intthreadId=Thread.CurrentThread.ManagedThreadId;
  48. intwaitTimes=0;
  49. while(_dbThreadIdDict.ContainsKey(_connString)&&_dbThreadIdDict[_connString]!=threadId)
  50. {
  51. Thread.Sleep(WAIT_TIME);
  52. waitTimes+=WAIT_TIME;
  53. #ifDEBUG
  54. Console.WriteLine(_connString+"waitfor"+waitTimes+"ms");
  55. #endif
  56. if(waitTimes>sqliteWriteLockTimeout)
  57. {
  58. thrownewTimeoutException("sqlite等待写操作超时");
  59. }
  60. }
  61. lock(locker)
  62. {
  63. if(!_dbThreadIdDict.ContainsKey(_connString))
  64. _dbThreadIdDict.Add(_connString,threadId);
  65. }
  66. }
  67. privatevoidReleaseWriteLock()
  68. {
  69. lock(locker)
  70. {
  71. if(_dbThreadIdDict.ContainsKey(_connString))
  72. {
  73. _dbThreadIdDict.Remove(_connString);
  74. }
  75. }
  76. }
  77. #endregion
  78. #regionIdisposable成员
  79. publicvoiddispose()
  80. {
  81. ReleaseWriteLock();
  82. }
  83. #endregion
  84. }

希望此文有用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐