Malagu 框架提供了一个装饰器 @Transactional 可以在方式上以声明的方式定义事务的相关行为,Malagu 框架会根据装饰器声明的情况来决定事务的开启、传播、回滚和提交。
@Transactional
装饰器配置选项:
export interface TransactionalOption {name?: string; // 多数据源链接情况下,指定数据源链接名称,默认为 defaultisolation?: IsolationLevel; // 数据库隔离级别propagation?: Propagation; // 事务的传播行为,支持 Required 和 RequiresNew,默认为 RequiredreadOnly?: boolean; // 只读,不开启事务,默认为开启事务}
示例
@Put()@Transactional()async modify(@Body() user: User): Promise<void> {const repo = OrmContext.getRepository(User);await repo.update(user.id, user);}
@Transactional 与 OrmContext 关系
Malagu 框架会根据装饰器的配置在方法调用前开启事务(也可能不开启),然后把开启事务的 EntityManager 托管在 OrmContext 上下文中,所以通过 OrmContext 就能够取到框架帮我们开启过事务的 EntityManager,其中 Repository 也是通过托管的 EntityManager 创建的,为了正确的取到 EntityManager,请确保装饰器配置的名称与 OrmContext 获取 EntityMananger 的名称保持一致。方法执行完后,框架根据方法的执行情况,会自动决定事务是提交还是回滚,方法执行出现异常则事务回滚,否则事务提交。
数据库查询
数据库查询大部分情况不需要开启事务,但是您也最好在方式加上 @Transactional 装饰器,然后通过 readonly 配置为 true,让框架为您创建一个不开启事务的 EntityManager。如下:
@Get()@Transactional({ readOnly: true })list(): Promise<User[]> {const repo = OrmContext.getRepository(User);return repo.find();}
事务传播行为
目前支持两种事务传播行为:
export enum Propagation {Required, RequiresNew}
说明:
- Required 需要开启一个事务,如果上一层方法已经开启过事务,则复用上一个事务,否则开启一个新事务
 - RequiresNew 不管上一层方法有没有开启过事务,都开启一个新事物
 
注意:事务在不同的方法传播的时候,请保证方法之间是同步调用的。比如:
**
...@Transactional()async foo(): Promise<void> {...await bar(); // 必须加上 await}.......@Transactional()async bar(): Promise<void> {...}....
