Я получаю сообщение об ошибке: выполняется запрос к освобожденному или потерянному соединению в операторе else - PullRequest
0 голосов
/ 01 октября 2019

Вот код, я пытаюсь проверить результат оператора вставки. Если он равен нулю (если заголовок тега уже существует), он должен выполнить оператор else. Но он не работает в операторе else, выдавая ошибку потерянного соединения.

 return this.store.tx('create-tags', async (transaction: any) => {
    tagDetails.forEach((tag: any) => {
     transaction
      .oneOrNone(
      `INSERT INTO tag(title)
         VALUES ($1)
         ON CONFLICT DO NOTHING
         RETURNING tag_id, title`,
        [tag.title],
      )
        .then((result: any) => {
            console.log('the tag details are', result);
           if (result !== null) {
              this.createTags(collectionId, tag.item_id, result.tag_id);
            } else {
           transaction.oneOrNone(
           `
           SELECT tag_id
           FROM tag
           WHERE title = $1
           `,
           [tag.title],
              ).then((tagId: string) => {
               console.log('the tagid in else statement is', tagId);
              if (tagId) {
                this.createTags(collectionId, tag.item_id, tagId);
               }
             })
             .catch(err => {
               console.log('the error in else statement is', err);
             });
       }
      });
  });

1 Ответ

0 голосов
/ 02 октября 2019

В вашем коде обнаружен ряд проблем.

Основная и причина возникновения ошибки заключается в том, что вы не сумели связать результат запросов с результатом транзакции. В результате вы получите несколько запросов, которые будут выполняться вне контекста транзакции, что приводит к ошибке. Вот модифицированная версия, которая об этом позаботится:

return this.store.tx('create-tags', t => {
    const res = tagDetails.map((tag: any) => {
        return t.oneOrNone(`INSERT INTO tag(title) VALUES ($1) ON CONFLICT DO NOTHING RETURNING tag_id, title`,
            [tag.title],
        )
            .then((result: any) => {
                console.log('the tag details are', result);
                if (result !== null) {
                    return this.createTags(collectionId, tag.item_id, result.tag_id);
                } else {
                    return t.oneOrNone(`SELECT tag_id FROM tag WHERE title = $1`, [tag.title])
                        .then((tagId: string) => {
                            console.log('the tagid in else statement is', tagId);
                            if (tagId) {
                                return this.createTags(collectionId, tag.item_id, tagId);
                            }
                        })
                        .catch(err => {
                            console.log('the error in else statement is', err);
                        });
                }
            });
    });
    return t.batch(res);
});

Однако, это не особенно хорошо по следующим причинам:

  • Вы должны переписать его, используя полностью async code
  • Вы должны обрабатывать ошибки вне транзакции
  • Весь ваш код выглядит так, как будто его можно заменить одним запросом.
  • Мы не знаем, что createTags делает, поэтому не может комментировать это
...