【问题标题】:Mikroorm check if entity is deletedMikroorm 检查实体是否被删除
【发布时间】:2021-07-19 17:54:30
【问题描述】:

em.nativeDelete 返回有多少实体被删除,所以我可以这样做:

const count = await this.em.nativeDelete(User, {id});

if(!count){
    throw new EntitiyNotFoundException(`User with id: ${id} is not found`);
}

有没有办法用 remove() 做同样的事情。它返回 EntityManager 我如何检查是否删除了实体:

const user = this.em.getReference(User, id);
await this.em.remove(user); 

【问题讨论】:

    标签: mikro-orm


    【解决方案1】:

    使用em.remove(),您首先需要加载实体以查看它是否存在,无法从 UoW 访问已删除的计数,因为刷新不绑定到该特定查询,它可以包含许多查询不同的实体/表和操作 (CRUD)。

    您希望在显式事务中执行此操作,以确保其他请求不会删除您刚刚从数据库中检索到的记录。

    await em.transactional(async em => {
      // this will throw if not found, you might want to use `em.findOne` and 
    throw yourself
      const user = await em.findOneOrFail(User, id);
      em.remove(user); // flush will be called automatically when using explicit transactions
    });
    

    【讨论】:

    • 我使用这种方法只是不想两次访问数据库?如果 findOneOrFail 会抛出并且无论如何都无法到达 remove 或者只是省略刷新,是否有理由将其包装在事务中?
    • 如果您在事务中不执行两个查询,您可能会面临竞争条件(两个请求尝试执行相同操作,两者都会通过查找检查,但只有一个会实际删除实体)。否则选择查询将在事务之外执行
    • 我认为事务与并发无关。因为无论如何都会在事务结束时调用刷新和提交。在文档中,有一种乐观锁定,它使用锁定来处理这种行为mikro-orm.io/docs/transactions/#optimistic-locking。 mikroOrm 是否默认在同一页面顶部进行了事务性解释?
    • 它与并发有关。刷新将在事务中运行事物,但您希望该选择也成为其中的一部分,并且刷新仅与写入有关(创建/更新/删除查询)。乐观锁定适用于更新,我们在这里讨论删除。
    • 是的,但是一个事务只有在刷新之后才能看到另一个事务的工作,所以即使你将它包装在事务中,它们都可以采用相同的实体并且会有竞争条件。因为 transactinal 不会锁定另一个事务以获取相同的实体,并且在同一页面中存在:“悲观写入 (LockMode.PESSIMISTIC_WRITE),为并发读取和写入操作锁定底层数据库行。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-28
    • 2011-12-10
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多