用 sequelize.js 操作 sqlite3 数据库在并发写事务时,出现 "SQLITE_BUSY" 的报错,但在用 knex.js 时
时间: 2020-08-20来源:V2EX
前景提要
虽然我知道 sqlite 数据库本身是不支持并发写事务的,应该是 knex.js 在执行的时候做了相应处理。但我在 knex.js 和 sequelize.js 的文档里都没找到关于 sqlite 该如何处理并发写事务的说明。
所以,让我困惑的问题有两个: knex.js 和 sequelize.js 在处理 sqlite 数据库的并发写事务时的区别是什么? 如果选择使用 sequelize.js 操作 sqlite 数据库,又该如何处理并发写事务?
有熟悉 sequelize 和 knex.js 这两个库的 v 友吗?
下面是部分代码段,为了方便重现报错,我写了一个小 demo, https://github.com/Watanuki-Kimihiro/sqlite-busy
byKnex // sqlite-busy/byKnex/db.js const insertWorkMetadata = work => knex.transaction(trx => trx.raw( // insert or ignore into `t_circle` (`id`, `name`) values (12345, 'Circile_Name') trx('t_circle') .insert({ id: work.circle.id, name: work.circle.name, }).toString().replace('insert', 'insert or ignore'), ) .then(() => trx('t_work') .insert({ id: work.id, title: work.title, circle_id: work.circle.id }))); createSchema() .then(() => { let work = { id: 123456, title: 'Work_Title', circle: {id:12345, name:'Circile_Name'} }; let promises = []; for (let i=1; i<10; i++) { let newWork = JSON.parse(JSON.stringify(work)); newWork.id = work.id + i; promises.push(insertWorkMetadata(newWork)); } return Promise.all(promises); }) .then(() => {console.log("finished")}) .catch((err) => { console.error(err); });
bySequelize // sqlite-busy/bySequelize/db.js const insertWorkMetadata = work => sequelize.transaction(t => { return Circle.findOrCreate({ where: {id: work.circle.id}, defaults: {name: work.circle.name}, transaction: t }) .then(([circle, created])=> { return circle.createWork({ id: work.id, title: work.title, }, {transaction: t}); }); }); sequelize.sync() .then(() => { let work = { id: 123456, title: 'Work_Title', circle: {id:12345, name:'Circile_Name'} }; let promises = []; for (let i=1; i<10; i++) { let newWork = JSON.parse(JSON.stringify(work)); newWork.id = work.id + i; promises.push(insertWorkMetadata(newWork)); } return Promise.all(promises); }) .then(() => {console.log("finished")}) .catch((err) => { console.error(err); });

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

热门排行