AlexiaChen.github.io
AlexiaChen.github.io copied to clipboard
SQLite的并发
title: SQLite的并发 date: 2017-02-23 17:48:40 tags:
- SQLite
- 数据库
以前没有好好看过SQLite,并没有对它有更深入点的了解,就当软件本地的配置文件和小规模数据统计来使用,对它的一些知识不是很清晰,今天就借助SQLite官方文档选择性的了解下,主要关注并发,多线程和多进程访问
多个进程应用实例是否能同时访问单个数据库文件?
多进程能同时打开一个数据库,多进程也能同时对一个数据库进行SELECT,但是任意一时刻,有且仅有一个进程能修改一个数据库。
SQLite使用读写锁来控制数据库的访问。但是,使用时请注意:这种锁机制可能在网络文件系统(NFS)上不能正确工作。所以,应该避免多进程访问一个在网络文件系统上的数据库文件。另外,在Windows下,这个锁机制如果在不运行Share.exe守护进程的情况下,在FAT文件系统下就无法工作,由于锁机制,数据库文件在Windows网络共享中多进程访问有严重BUG,所以不要在多台Windows机器之间共享数据库文件。
应该明白,没有一个为嵌入式设计的数据库会支持高并发的,SQLIte允许多进程同时打开,读取数据。但是多进程写数据库下,当任意一个进程想写的话,那么在进程修改数据库期间SQLite会锁住整个数据库文件。但是这样一般只会耗费几毫秒。其他进程只用简单等待锁释放就可以进行操作了。
如果有高并发的需求,一定选择C/S模型的数据库(MySQL,SQLserver,PostgreSQL)。
但是,从经验上讲,大多数应用程序不需要这么大的并发。
当SQLite试图访问一个被其他进程锁住的数据库文件,那么SQLite默认行为会返回SQLITE_BUSY。
SQLite是否线程安全?
是的,如果要让SQLite支持线程安全,就使用SQLITE_THREADSAFE预编译宏来编译SQlite。当然,不用担心,Windows和Linux的二进制发布版就是这样编译的。
SQLite支持线程安全是为了用互斥量同步公共的数据结构。然而要请求和释放锁,所以SQLite性能会略有下降。如果开发者没有线程安全这样的需求,可以重新编译SQLite,关闭互斥量以得到最大性能。
实际上加锁不会太影响性能,影响性能的是锁争用,如果不是多线程,我觉得也可以单线程程序使用线程安全版本的SQLite。