SQLite并发访问出现The database file is locked , database is locked

前端之家收集整理的这篇文章主要介绍了SQLite并发访问出现The database file is locked , database is locked前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

站点服务端使用sqlite存储一些临时数据,但是在多人并发的时候sqlite会抛出异常:The database file is locked,database is locked

sqlite的特点:

  1. 简单(simple):sqlite是一个非常轻量级自包含(lightweight and self-contained)的DBMS:一个头文件,一个动态库文件,你就拥有了关系数据库的所有功能了。简单,是sqlite最明显的哲学。它提供的API少而简单。只需要一个DLL文件,你的程序马上就拥有了一个功能强大的数据库引擎,这是一件很美妙的事。
  2. 小巧(small):我用VS 2005在Windows下编译的3.6.11,Release版为368K,用时不到20秒——而编译MysqL时,要花上几分钟。而当我插入10000条int数据时,内存开销660K,磁盘开销92K。
  3. 事务(transaction):事务是现代商业数据处理系统最基本的要求,而Access,不论是在可执行文件大小(看了一下Access2003的可执行文件大小为6.32M,两者不是一个量级),还是事务特性,都是不能和sqlite 相比的。
  4. 并发性(Concurrency):由于sqlite通过OS的文件锁来实现库级锁,粒度很大,但是,它通过一些复杂特殊的处理(具体可以参见分析系列),尽量的提升了读写的并发度。
  5. sql92:sqlite支持绝大部分的标准sql语句,你只需要几百K的空间,就可以换来需要上百兆的通用DBMS几乎所有操作了。
  6. 方便(Convenience):如果你的程序要使用sqlite,只需要将拷贝你的程序目录即可。
  7. 开源(Opensource):这是它最强大的地方。开源,意味着你可以品读它的源码,你可以随时修改它,加入你自己的特性,而这一切完全免费的。

  sqlite只支持库级锁,库级锁意味着什么?——意味着同时只能允许一个写操作,也就是说,即事务T1在A表插入一条数据,事务T2在B表中插入一条数据,这两个操作不能同时进行,即使你的机器有100个cpu,也无法同时进行,而只能顺序进行。表级都不能并行,更别说元组级了——这就是库级锁。但是,sqlite尽量延迟申请X锁,直到数据块真正写盘时才申请X锁,这是非常巧妙而有效的。

sqlite不支持并发执行写入操作,即使是不同的表,只支持库级锁,而且这个sqlite本身没有实现,必须自己实现这个库级锁。

综上所述,对于库级锁的数据库,可以定义一个全局的锁变量,在所有需要发起事务的操作中使用同步机制访问数据库

class PublicationEventHandler implements JobEventHandler {
    public static final Object sqlITE_DBLEVEL_LOCK = new Object();
    @Override
    public void onCompleted(JobEvent event) {
	synchronized (sqlITE_DBLEVEL_LOCK) {
	    ServiceLocator.getJobNotificationService().markJobNotified(event.getJobCommand().getIdentity(),JobStatusDefinition.COMPLETE);
	}

    }

    @Override
    public void onCancelled(JobEvent event) {
	synchronized (sqlITE_DBLEVEL_LOCK) {
	    ServiceLocator.getJobNotificationService().markJobNotified(event.getJobCommand().getIdentity(),JobStatusDefinition.CANCEL);
	}
    }

    @Override
    public void onFailed(JobEvent event) {
	synchronized (sqlITE_DBLEVEL_LOCK) {
	    ServiceLocator.getJobNotificationService().markJobNotified(event.getJobCommand().getIdentity(),JobStatusDefinition.FAIL);
	}
    }

    @Override
    public void onStart(JobEvent event) {
	synchronized (sqlITE_DBLEVEL_LOCK) {
	    ServiceLocator.getJobNotificationService().addJobNotification(event.getJobCommand().getIdentity());
	}
    }

}
原文链接:https://www.f2er.com/sqlite/200070.html

猜你在找的Sqlite相关文章