虽然我知道 sqlite 数据库本身是不支持并发写事务的,应该是 knex.js 在执行的时候做了相应处理。但我在 knex.js 和 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);
});