当前位置: 首页 > 知识库问答 >
问题:

NESTJS/TypeOrm数据库事务

吉俊德
2023-03-14

假设我们有两个服务,A和B。服务A有一个函数执行以下操作:

  1. 验证数据

现在,让我们假设以下步骤之一,步骤3或4失败。由于服务B对数据库进行了更改,这些更改仍然存在。

在这种情况下,有没有办法回滚数据库?我曾考虑过数据库事务,但在nest js中找不到任何方法来实现这一点,尽管TypeOrm支持它,但nest看起来并不自然。如果不是的话,我现在被服务B所做的更改“卡住”了,但是如果没有服务B所做的更改,A应该已经做了。

多谢了。

共有3个答案

左翰海
2023-03-14

typeorm事务性cls hooked使用cls(延续本地存储)在不同的存储库和服务方法之间处理和传播事务。

@Injectable()
export class PostService {
  constructor(
    private readonly authorRepository: AuthorRepository,
    private readonly postRepository: PostRepository,
  ) {}

  @Transactional() // will open a transaction if one doesn't already exist
  async createPost(authorUsername: string, message: string): Promise<Post> {
    const author = await this.authorRepository.create({ username: authorUsername });
    return this.postRepository.save({ message, author_id: author.id });
  }
}
林元明
2023-03-14

以下是我如何解决它,因为我需要使用悲观锁。

我觉得这是一种“嵌套”方式,因为你可以简单地要求NestJS注入一个TypeormConnection的实例,你就可以开始了。

@Injectable()
class MyService {
  // 1. Inject the Typeorm Connection
  constructor(@InjectConnection() private connection: Connection) { }

  async findById(id: number): Promise<Thing> {
    return new Promise(resolve => {
      // 2. Do your business logic
      this.connection.transaction(async entityManager => {
        resolve(
          await entityManager.findOne(Thing, id, {
            lock: { mode: 'pessimistic_write' },
          }),
        );
      });
    });
  }
}

只需将所需的任何其他逻辑放入中即可。事务阻塞,您就可以开始了。

注意:您必须使用由提供的entityManager。事务方法,否则它将无法工作。

宣星光
2023-03-14

许多解决方案是可用的,它们都应该基于SQL事务管理。

就我个人而言,我认为实现这一点的最简单方法是在数据库上执行代码时使用相同的EntityManager实例。然后你可以使用这样的东西:

getConnection().transaction(entityManager -> {
    service1.doStuff1(entityManager);
    service2.doStuff2(entityManager);
});

您可以从EntityManager实例生成QueryRunner,如果您在ORM操作之外执行原始SQL,该实例将被包装在同一事务中。您还需要从EntityManager生成Repository实例,否则它们将在主事务之外执行代码。

 类似资料:
  • 问题内容: 关于如何在本期中执行此操作的讨论很长时间。 我已经尝试了许多建议的解决方案,但运气不佳。 谁能提供一个具体示例,说明如何使用注入的存储库和模拟数据来测试服务? 问题答案: 假设我们有一个非常简单的服务,该服务通过id查找用户实体: 然后,您可以使用以下模拟工厂模拟(根据需要添加更多方法): 使用工厂可确保为每个测试使用新的模拟。 为了确保类型安全和舒适,您可以在模拟中使用以下类型(远非

  • 我正在尝试使用NestJS和TypeORM为我的数据库设置种子。 我有一个迁移文件,它创建了一个表,还有一个种子文件,它将一个插入到表中。这些文件的主要区别是迁移文件直接运行查询: 当种子文件获取存储库时: 这个是产生错误的那个。 在一个服务中,我获得了存储库并保存了实体,没有任何问题。问题只在播种时发生。 我注册打字格式如下: 哪里: 我正在使用使用以下网页配置编译和服务应用程序: 我的结构最终

  • 我使用NestJS与TypeOrm连接在MySQL,但返回一个错误:'没有存储库的"用户"被发现。看起来这个实体没有注册在当前的“默认”连接中?' 没有TypeOrm,我可以运行服务器。 “用户”是我的实体。 app.module 使用者单元 user.entity 谁能告诉我怎么了? 谢谢你的帮助!

  • NestJS的新手,遇到了一个问题。对于我们的部署,我们需要从AWS Parameter Store(Systems Manager)获取配置,包括数据库连接字符串。我有一个配置模块和配置服务,它基于参数存储路径检索我的环境的所有参数存储项: 这是我的配置服务: 下面是主要的应用模块声明块: 如您所见,我正在告诉TypeForm在ConfigService中调用getDatabase()方法,但问

  • 所以我正在用NestJs和mongodb进行一个项目。早些时候,我们使用express和mongoose,为了在数组列中查找结果,我们使用了如下方法: 现在,当我们使用TypeORM迁移到新的Nest后端时,我们使用的是: 但这不起作用。奇怪的是,除此之外,我们在mongoose中使用的所有查询都能正常工作。我试着用NestJS处理mongoose,这确实有效,所以函数参数或任何东西都没有问题。

  • 假设有两个数据库,其中date数据库的表每天一张,表名根据日期创建:20230801,20230802... 要根据请求的接口参数日期范围,动态去连接表查询该如何操作呢? 实体指定表名查询是OK的。 上面的实体没有指定表名,每次查询自动创建了一个 date 表 。。 目前数据库有如下表: 20230801 20230802 20230803 我想的是根据查询的参数去动态查询这些表,可能是一张也可能