• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

트랜잭션이 반복됩니다

22.06.13 00:42 작성 조회수 234

0

로그인 하는 동안 동일한 트랜잭션이 반복됩니다.

코드는 13강 강의한 내용에서 바뀐점은 없습니다.

돈이 계속 빠져나갑니다...

답변 1

답변을 작성해보세요.

0

진짜 돈인줄 알고 깜짝 놀랐네요 ㅎㅎ 저거 경매 끝난 것 찾는 쿼리가 잘못된 것 같은데요??

wdhgood123님의 프로필

wdhgood123

질문자

2022.06.13

module.exports = async () => {
    console.log('checkAuction');
    try {
    const yesterday = new Date();
    yesterday.setDate(yesterday.getDate() - 1); // 어제 시간
    const targets = await Good.findAll({
      where: {
        SoldId: null,
        createdAt: { [Op.lte]: yesterday },
      },
    }); // 경매 시작 후 24시간이 지나도 낙찰을 받지 못한 상품
    targets.forEach(async (target) => {
      const success = await Auction.findOne({
        where: { GoodId: target.id },
        order: [['bid', 'DESC']],
      });
      await Good.update({ SoldId: success.UserId }, { where: { id: target.id } });
      await User.update({
        money: sequelize.literal(`money - ${success.bid}`),
      }, {
        where: { id: success.UserId },
      });
    }); // 낙찰자 지정
    const unsold = await Good.findAll({
        where: {
          SoldId: null,
          createdAt: { [Op.gt]: yesterday },
        },
    });
    unsold.forEach((target) => {
        const end = new Date(unsold.createdAt);
        end.setDate(end.getDate() + 1);
        schedule.scheduleJob(end, async () => {
            const t = await sequelize.transaction();
            try {
                const success = await Auction.findOne({
                where: { GoodId: target.id },
                order: [['bid', 'DESC']],
                transaction: t,
            });
            await Good.update({ SoldId: success.UserId }, { where: { id: target.id }, transaction: t });
            await User.update({
                money: sequelize.literal(`money - ${success.bid}`),
            }, {
                where: { id: success.UserId },
                transaction: t,
                });
            await t.commit();
            } catch (error) {
                await t.rollback();
            }
        })
    });
    } catch (error) {
        console.error(error);
    }
};

경매 끝난 것 찾는 쿼리가 정확이 어떤 것인가요? 

위 코드는 checkAuction.js 코드이며

router.post('/good', isLoggedIn, upload.single('img'), async (req, res, next) => {
  try {
    const { name, price } = req.body;
    const good = await Good.create({
      OwnerId: req.user.id,
      name,
      img: req.file.filename,
      price,
    });
    const end = new Date();
    end.setDate(end.getDate() + 1);
    schedule.scheduleJob(end, async () => {
      const t = await sequelize.transaction();
      try {
        const success = await Auction.findOne({
          where: { GoodId: good.id },
          order: [['bid', 'DESC']],
          transaction: t,
      });
        await Good.update({ SoldId: success.UserId }, { where: { id: good.id }, transaction: t });
        await User.update({
          money: sequelize.literal(`money - ${success.bid}`),
        }, {
          where: { id: success.UserId },
          transaction: t,
        });
        await t.commit();
      } catch (error) {
        await t.rollback();
      }
    })
    res.redirect('/');
  } catch (error) {
    console.error(error);
    next(error);
  }
});

상품을 가져오는 코드입니다.

강의 내용에서 따로 고친것은 없습니다.

 

코드 자체는 문제 없습니다. 저기 로그에서 SoldId, good.Id 같은 게 ?로 뜨는 데 이 부분을 console.log찍어서 직접 값을 확인하고, DB에서도 워크벤치로 제대로 들어있는지 확인이 필요합니다. SoldId가 null로 계속 유지되어서 자꾸 저 로직이 실행되는게 아닌가싶기도 하네요.

저 unsold 부분 직접 짜신 건가요? 제가 개정판에서 추가하려고 작성한 코드랑 거의 일치하네요. 저는 Good.update부분만 await good.setSold(success.UserId, { transaction: t })로 수정하긴 했습니다.

wdhgood123님의 프로필

wdhgood123

질문자

2022.06.13

const unsold = await Good.findAll({
        where: {
          SoldId: null,
          createdAt: { [Op.gt]: yesterday },
        },
    });
    unsold.forEach((target) => {
        const end = new Date(unsold.createdAt);
        end.setDate(end.getDate() + 1);
        schedule.scheduleJob(end, async () => {
            const t = await sequelize.transaction();
            try {
                const success = await Auction.findOne({ // 경매를 내림차순으로 정렬한 것 중 첫번째(가장 큰 가격)
                where: { GoodId: target.id },
                order: [['bid', 'DESC']],
                transaction: t,
            });
            // await good.setSold(success.UserId)와 같다
            await Good.update({ SoldId: success.UserId }, { where: { id: target.id }, transaction: t });
            await User.update({
                money: sequelize.literal(`money - ${success.bid}`),
            }, {
                where: { id: success.UserId },
                transaction: t,
                });
        console.log(success.UserId);
        console.log(Good.id);
        console.log(unsold.createdAt);
        console.log(end);
            await t.commit();
            } catch (error) {
                await t.rollback();
            }
        })
    });
    } catch (error) {
        console.error(error);
  }

이 코드는 강의에 나와있는 코드입니다.

왜 이런 현상이 나온 것인지 파악했습니다.

서버를 재시작하면 위에 보시다시피 트랜잭션이 반복됩니다.

app.js의 checkAuction(); 호출로 실행되는것 같습니다.

그 중에서도 위에 올린 코드가 실행됩니다.

코드대로라면  스케쥴 모듈로 unsold.createAt에서 하루가 지난 Date에 실행되어야 하지만

콘솔로 찍어보니

이렇게 찍힙니다.

참고로 

시퀄라이즈에서 ?가 뜨는데 콘솔이나 워크벤쳐로 확인해보면 제대로 데이터가 저장됩니다.

왜 ?가 뜨는지는 잘 모르겠습니다

 

?는 시퀄라이즈가 의도적으로 데이터를 숨겨주는 겁니다. 보안사고 방지를 위해서요. createdAt이 제대로 시퀄라이즈 모델 같은 데도 들어있나요?

wdhgood123님의 프로필

wdhgood123

질문자

2022.06.14

네. 생성될때에도 제대로 생성됩니다.

워크벤쳐에도 있습니다.

아 unsold.createdAt이 아니라 target.createdAt 하셔야합니다.