python多线程访问sqlite3_SQLite3性能优化1-多线程插入或者查询操作方面

先看看总结的结论:

A.  由此可见,要想保证线程安全的话,可以有这4种方式:

SQLite使用单线程模式,用一个专门的线程访问数据库。

SQLite使用单线程模式,用一个线程队列来访问数据库,队列一次只允许一个线程执行,队列里的线程共用一个数据库连接。

SQLite使用多线程模式,每个线程创建自己的数据库连接。

SQLite使用串行模式,所有线程共用全局的数据库连接。

B.  关于数据库连接和数据库事务,以及线程之间的关系对应

事务是和数据库连接相关的,与线程是无关的。一个数据库连接同时只能执行一个事务操作。

每个数据库连接(使用pager来)维护自己的事务,且同时只能有一个事务(但是可以用SAVEPOINT来实现内嵌事务)。也就是说,事务与线程无关,一个线程里可以同时用多个数据库连接来完成多个事务,而多个线程也可以同时(非并发)使用一个数据库连接来共同完成一个事务。

经常有人抱怨SQLite的插入太慢,实际上它可以做到每秒插入几万次,但是每秒只能提交几十次事务。因此在插入大批数据时,可以通过禁用自动提交来提速。数据库只有在事务中才能被更改。所有更改数据库的命令(除SELECT以外的所有SQL命令)都会自动开启一个新事务,并且当最后一个查询完成时自动提交。

一、 是否支持多线程?

SQLite官网上的“Is SQLite threadsafe?”这个问答。 简单来说,从3.3.1版本开始,它就是线程安全的了。而iOS的SQLite版本没有低于这个版本的,当然,你也可以自己编译最新版本。

不过这个线程安全仍然是有限制的,在这篇《Is SQLite thread-safe?》里有详细的解释。

另一篇重要的文档就是《SQLite And Multiple Threads》。它指出SQLite支持3种线程模式:

单线程:禁用所有的mutex锁,并发使用时会出错。当SQLite编译时加了SQLITE_THREADSAFE=0参数,或者在初始化SQLite前调用sqlite3_config(SQLITE_CONFIG_SINGLETHREAD)时启用。

多线程:只要一个数据库连接不被多个线程同时使用就是安全的。源码中是启用bCoreMutex,禁用bFullMutex。实际上就是禁用数据库连接和prepared statement(准备好的语句)上的锁,因此不能在多个线程中并发使用同一个数据库连接或prepared statement。当SQLite编译时加了SQLITE_THREADSAFE=2参数时默认启用。若SQLITE_THREADSAFE不为0,可以在初始化SQLite前,调用sqlite3_config(SQLITE_CONFIG_MULTITHREAD)启用;或者在创建数据库连接时,设置SQLITE_OPEN_NOMUTEX flag。

串行:启用所有的锁,包括bCoreMute

你可能感兴趣的:(python多线程访问sqlite3_SQLite3性能优化1-多线程插入或者查询操作方面)