EggBornJS provides more convenient database transaction
support. Let’s look at how database transaction
is supported in EggJS
and EggBornJS
respectively
EggJS
const conn = await app.mysql.beginTransaction(); // begin
try {
await conn.insert(table, row1); // step one
await conn.update(table, row2); // step two
await conn.commit(); // commit
} catch (err) {
// error, rollback
await conn.rollback(); // must rollback on error!!
throw err;
}
EggBornJS
In EggBornJS, there is no need to change the code related to accessing the database, just declare the middleware transaction
in the API route
src/suite-vendor/test-party/modules/test-party/backend/src/routes.js
// test
{ method: 'post', path: 'kitchen-sink/guide/echo8', controller: testKitchensinkGuide, middlewares: 'transaction' },
Whether
ctx.db
ormodel
is used to operate the database, when the middlewaretransaction
is enabled, the same database connection object is automatically maintained in the context environment, thus facilitating support fordatabase transaction
API Route Performing-Chain
As mentioned earlier, One API Route
can be performed by another API Route
in backend, thus forming the performing-chain
Since each API Route
can specify middleware transaction
separately, then what are the operaion rules of transaction
in the performing-chain
?
Basic Rules
- At most one
database transaction
can be created in anperforming-chain
. that is, there is no concept ofchild transaction
ornested transaction
- When the first
API Route
has enabledtransaction
, the subsequentAPI Routes
will automatically be in the previously enabledtransaction
regardless of whether specified the middlewaretransaction
Perform after Transaction
In some special scenarios, codes need to be performed after the current database transaction is committed. At this time, you can register an asynchronous method through the method of ctx.tail
src/suite-vendor/test-party/modules/test-party/backend/src/controller/test/ctx/tail.js
const require3 = require('require3');
const assert = require3('assert');
module.exports = app => {
class TailController extends app.Controller {
async tail() {
// 1
this.ctx.meta._cache = 1;
// tail
this.ctx.tail(() => {
assert.equal(this.ctx.meta._cache, 2);
});
// 2
this.ctx.meta._cache = 2;
// done
this.ctx.success();
}
}
return TailController;
};
Comments: