knex использовать count () в качестве значения для вставки новой строки - PullRequest
0 голосов
/ 23 июня 2019

Я пытаюсь использовать count () в качестве значения для вставки новой строки.Проблема в том, что в случае многопоточности я получаю неправильное значение для count (), так как текущий код не работает должным образом с транзакцией.

Я пробовал много способов, чтобы добиться блокировкис явной транзакцией knex и без нее, но не удалось получить правильное значение count ().

  const now = knex.fn.now();

  const [{ count }] = await knex
    .count()
    .from(STUDENTS)
    .where(CLASS_ID_COL, classId)
    .then(daoUtils.normalize);

  const [id] = await knex
    .insert(
      {
        [CREATED_AT_COL]: now,
        [UPDATED_AT_COL]: now,
        [CLASS_ID_COL]: classId,
        [ORDER_COL]: Number(count)
      },
      ID_COL
    )
    .into(STUDENTS);

Заранее спасибо.

1 Ответ

0 голосов
/ 23 июня 2019

Я нашел решение, используя .forUpdate ():

const now = knex.fn.now();

return knex.transaction(async trx => {

    const [id] = await knex
      .insert(
        {
          [CREATED_AT_COL]: now,
          [UPDATED_AT_COL]: now,
          [CLASS_ID_COL]: classId,
          [ORDER_COL]: Number(count)
        },
        ID_COL
      )
      .into(STUDENTS);

    const result = await trx
      .select("*")
      .forUpdate()
      .from(STUDENTS)
      .where(CLASS_ID_COL, classId);


    await trx.table(STUDENTS)
      .update(ORDER_COL, Number(result.length) - 1)
      .where(ID_COL, id);

    return id;

  });
...