小项目用 SQLite 很爽,一上并发就撞 database is locked。
原因:SQLite 写操作是全局锁,同一时刻只能有一个写。读可以并发,写不行。默认 busy_timeout 是 0,撞上锁立刻报错。
三种解法:
一、加 busy_timeout(最省事)
PRAGMA busy_timeout = 5000;写冲突时最多等 5 秒。适合写不频繁的场景,改一行就行。二、WAL 模式(推荐)
PRAGMA journal_mode = WAL;读写不互相阻塞,并发能力明显提升。注意 WAL 文件要跟着备份,不然恢复会丢数据。三、上独立数据库
写入 QPS 超过几十、或者有长事务,别硬扛。迁 MySQL 或 Postgres。我自己的分界线:单机应用、写操作少于每秒 10 次,SQLite + WAL + busy_timeout 完全够。再多就换。
还有一个坑:NFS 上跑 SQLite 会出锁失效,别这么干。
主楼这个坑很典型,我们上线时也遇到过。
继续逛逛