5 sql t-sql node.js sequelize.js
假设我们已经使用 Sequelize 模型实现了几个(虚拟)服务来访问我们的数据库:
export class AService {
// ... some other stuff
async updateSomeA(aId: number, value: string) {
let instanceA = await ModelA.findById(aId);
// need this update to use the transaction!
await instanceA.update({
some_field: value
});
}
}
export class BService {
// ... some other stuff
async updateB(bId: number, value: string) {
let instanceB = await ModelB.findById(bId);
// and this one as well!
await instanceB.update({
some_field_in_b: value
});
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们想从代码中的其他地方(比如 from )调用updateSomeAand ,但我们希望这些调用包含在事务中。updateBCService
class CService {
// ...stuff
async f() {
// == begin transaction
await AService.updateSomeA(1, 'blah!');
await BService.updateB(3, 'meh');
// == end transaction
}
}
Run Code Online (Sandbox Code Playgroud)
根据我通过文档收集的信息,为了通过事务保护代码,我需要将其包装在回调中或使用承诺。是对的吗?
如果是这样的话,那么我将被迫修改我的服务,并且可能有一些“支持交易”的方法版本,对吗?
你们知道是否有计划支持类似的事情
Transaction.begin("myAwesomeTransaction");
// ... every SQL generated in here is 'safe'
Transaction.end();
Run Code Online (Sandbox Code Playgroud)
当然,我们总是可以将交易作为所有服务函数中可选的最后一个参数,或者至少是具有副作用的服务函数(即deleteA,updateB, 等)。就像是:
// ... changed AService.updateSomeA
async updateSomeA(aId: number, value: string, t?: Sequelize.Transaction) {
let instanceA = await ModelA.findById(aId);
await instanceA.update({
some_field: value
}, {
transaction: t // we use the transaction if we get one
});
}
Run Code Online (Sandbox Code Playgroud)
但是我们的呢CService.f()?该函数应该创建交易并将其传递下来,还是期望交易作为可选参数?嗯,答案是两者兼而有之,不是吗?如果我们f()从其他服务调用作为较大事务的一部分,我们希望它接收该Transaction实例并使用它。另一方面,如果我们f()从外部(例如控制器)调用,我们不想在那里创建事务......对吗?!
所以,我们最终得到这样的结果:
// ... changed CService.f
async f(t?: Sequelize.Transaction) {
if(!t) return sequelize.transaction(_f); // using the autoCallback overload
else return _f(t);
async function _f(trans: Sequelize.Transaction) {
// ... actual code for f() goes here
}
}
Run Code Online (Sandbox Code Playgroud)
完美的?不……期待您的意见!
| 归档时间: |
|
| 查看次数: |
1103 次 |
| 最近记录: |