框架:j-spring
前言
上一章spring已经整合type-orm了,这次主要对type-orm自动化事务的处理进行封装。保证一次请求一个事务,中途出现异常回滚。
实现过程
1.添加一个事务装饰器-TX
export const Tx = () => spring.paramterAnnotationGenerator('sqlite-jdbc.Table','NoName',{},Tx);
使用样例:控制器遇到请求时,会自动反射生成事务实例。
@Controller('/api')
@Json()
class ApiController {
async toTest(@Tx() tx:EntityManager){
}
}
2.添加对TX进行解析的后置处理器
- 实现sprig-web提供的参数拦截接口SpringWebParamInteceptor即可。
- getAnnotation()代表处理的装饰器。
- getBean() 参给控制器的实际对象。(SpringTx是对EntityManager的简单封装,当作是后者即可)
- error,success分别是请求错误和成功时的回调。这里分别执行事务的回滚和提交操作。
@Component()
export class TxParamInteceptor implements SpringWebParamInteceptor<SpringTx> {
@Autowired({clazz:DataSource as Clazz})
dataSource:DataSource;
isSpringWebParamInteceptor(): boolean {
return true;
}
getAnnotation(): Function {
return Tx;
}
async getBean(_req: any, _res: any, _paramterAnnotation: Anntation): Promise<SpringTx> {
const queryRunner:QueryRunner = this.dataSource.createQueryRunner()
const manager:EntityManager = queryRunner.manager;
await queryRunner.startTransaction();
return new SpringTx(manager);
}
error(bean: SpringTx): void {
bean.e.queryRunner?.rollbackTransaction();
bean.e.queryRunner?.release();
}
success(bean: SpringTx): void {
bean.queryRunner?.commitTransaction();
bean.queryRunner?.release();
}
}
3.编写一个测试用例
请求地址: http://localhost:3000/testApi/toTestTx, 事务有对半的几率提交和回滚。
@Controller('testApi')
@Json()
export class TestApiController {
@Get()
async toTestTx(@Tx() tx:SpringTx){
const postList:Post[] = [];
for(let i =0 ;i<100;i++){
const post = new Post().of({
image:new Image().of({
name:'heloa'
}),
title:'hello',
likesCount:100,
text:'a lot str'
})
postList.push(post);
}
await tx.save(postList);
if(Math.random()>0.5)
throw 'occur error!'
return postList;
}
}
执行没问题
- 失败了浏览器打印错误原因,控制台打印回滚,数据库无数据。
query: SELECT "Image"."id" AS "Image_id", "Image"."crateTime" AS "Image_crateTime" FROM "Image" "Image" WHERE "Image"."id" = 536
node_modules/.pnpm/typeorm@0.3.10_pmxns7ckow5hp64uzurbpl2oxu/node_modules/typeorm/platform/PlatformTools.js:198
query: INSERT INTO "Post"("id", "crateTime", "title", "text", "likesCount", "imageId") VALUES (NULL, datetime('now'), ?, ?, 100, 536) -- PARAMETERS: ["hello","a lot str"]
node_modules/.pnpm/typeorm@0.3.10_pmxns7ckow5hp64uzurbpl2oxu/node_modules/typeorm/platform/PlatformTools.js:198
query: SELECT "Post"."id" AS "Post_id", "Post"."crateTime" AS "Post_crateTime" FROM "Post" "Post" WHERE "Post"."id" = 536
node_modules/.pnpm/typeorm@0.3.10_pmxns7ckow5hp64uzurbpl2oxu/node_modules/typeorm/platform/PlatformTools.js:198
occur error!
node_modules/j-spring-web/dist/j-spring-web.cjs.development.js:1116
query: ROLLBACK
- 成功了浏览器返回json数据,控制台打印提交,数据库存在数据。
query: SELECT "Image"."id" AS "Image_id", "Image"."crateTime" AS "Image_crateTime" FROM "Image" "Image" WHERE "Image"."id" = 536
node_modules/.pnpm/typeorm@0.3.10_pmxns7ckow5hp64uzurbpl2oxu/node_modules/typeorm/platform/PlatformTools.js:198
query: INSERT INTO "Post"("id", "crateTime", "title", "text", "likesCount", "imageId") VALUES (NULL, datetime('now'), ?, ?, 100, 536) -- PARAMETERS: ["hello","a lot str"]
node_modules/.pnpm/typeorm@0.3.10_pmxns7ckow5hp64uzurbpl2oxu/node_modules/typeorm/platform/PlatformTools.js:198
query: SELECT "Post"."id" AS "Post_id", "Post"."crateTime" AS "Post_crateTime" FROM "Post" "Post" WHERE "Post"."id" = 536
node_modules/.pnpm/typeorm@0.3.10_pmxns7ckow5hp64uzurbpl2oxu/node_modules/typeorm/platform/PlatformTools.js:198
query: COMMIT