• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

질문있습니다

21.08.24 17:09 작성 조회수 102

1

안녕하세요 제로초님.

트랜잭션에서 nest-typeorm폴더를 보니 트랜잭션이 적용이 안되어 있어서 back폴더의 express로 nest와 비교하며 공부하고 있습니다

router.post("/workspaces"isLoggedInasync (reqresnext=> {
  const t = await sequelize.transaction();
  try {
    const exWorkspace = await Workspace.findOne({
      where: { url: req.body.url },
    });
    if (exWorkspace) {
      await t.rollback();
      return res.status(404).send("사용중인 워크스페이스 URL입니다.");
    }
    const workspace = await Workspace.create(
      {
        name: req.body.workspace,
        url: req.body.url,
        OwnerId: req.user.id,
      },
      {
        transaction: t,
      }
    );
    await workspace.addMembers(req.user.id, { transaction: t });

    const channel = await Channel.create(
      {
        name: "일반",
        WorkspaceId: workspace.id,
      },
      {
        transaction: t,
      }
    );

    await channel.addMembers(req.user.id, { transaction: t });
    await t.commit();
    return res.json(workspace);
  } catch (error) {
    await t.rollback();
    next(error);
  }
});

1. 제가 이해한게 맞는지 헷갈립니당.  

각각 네개의 Workspace.create,  workspace.addMembers,  Channel.create, channel.addMembers

에 두번째 인수로 transaction:t를 넣어주고 있는데 이는 이 네개중 하나라도 에러가 나면 모두 rollback되어서 4개 전부다 초기화 됩니다. 4개다 성공하면 commit되어 데이터베이스에 성공적으로 접근됩니다.

제가 이해한것이 맞나요?..

2.

 const workspace = await Workspace.create(
      {
        name: req.body.workspace,
        url: req.body.url,
        OwnerId: req.user.id,
      },
      {
        transaction: t,
      }
    );
    await workspace.addMembers(req.user.id, { transaction: t });

    const channel = await Channel.create({
      name: "일반",
      WorkspaceId: workspace.id,
    });

    await channel.addMembers(req.user.id);

그런데 만약  Workspace.create,  workspace.addMembers,에만 두번째 인수로 transaction:t를 넣어주고

Channel.create, channel.addMembers에는 transaction:t를 빼주면 Channel.create, channel.addMembers에는  transaction에 적용을 받지는 않지만 정상적으로 디비에 저장되어야 하지 않나요?. 실제로 실험해보니 저장이 안되네요. 왜 그런지 궁금합니다

3.

 if (exWorkspace) {
      await t.rollback();
      return res.status(404).send("사용중인 워크스페이스 URL입니다.");
   }

여기서 t.rollback이 왜 필요한지 궁금합니다.  이 코드를 기준으로 위에 코드에서 workspace를 find하는 코드이고 커밋이나 transaction:t 를 해준곳이 없고   , 또한 어차피  return되면 초기화일텐데 여기서 t.rollback()을 해주는게 궁금합니다.

답변 1

답변을 작성해보세요.

0

1. 네 맞습니다. 4개가 세트가 된다고 보시면 됩니다.

2. 저 부분은 저장이 되는게 맞다고 판단되는데요. 백엔드 서버 콘솔에 찍히는 SQL을 직접 봐서 무슨 일이 생기는지 확인해봐야할 것 같습니다.

3. 저 부분은 필요 없습니다만 항상 예외 때는 롤백 적어주는 습관을 들이는 게 좋습니다. 하나라도 빼먹으면 치명적이거든요.