sprinb-web 整合type-orm(12)

109 阅读2分钟

框架: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