Тупик Postgresql при вставке и обновлении

Ниже приведен журнал postgres.

Process 10396 waits for RowShareLock on relation 17204 of database 16384; blocked by process 10377.
Process 10377 waits for ShareLock on transaction 149848948; blocked by process 10396.
Process 10396: insert into "completed_jobs" ("id", ....... "limitation_code") values ($1, ...... $22) returning "id"
Process 10377: UPDATE jobs SET status='pending', updated_at=$1 WHERE id=$2

Я выполняю это из go Lang. Итак, это внутри распределенной среды.

Обновление нормальное исполнение,

    _, err = tx.Exec("UPDATE jobs SET status='pending', updated_at=$1 WHERE id=$2", time.Now().UTC(), job.Id)
    if err != nil {
        log.Println(getMessagePrefix(job, nil), "Error updating job status to pending", err)
    }
    err = tx.Commit()

Вставка находится внутри транзакции,

tx, _ := db.Begin()
tx.Exec("UPDATE jobs SET status=$1 WHERE id=$6", status)
tx.Exec("INSERT INTO completed_jobs SELECT * FROM jobs WHERE id=$1", job.Id)
tx.Exec("DELETE FROM jobs WHERE id=$1", job.Id)
err := tx.Commit()

person Naveen Kumar    schedule 09.06.2016    source источник


Ответы (1)


В очереди заданий я обычно использовал следующие стратегии, чтобы предотвратить попытки нескольких процессов получить доступ к одним и тем же заданиям. В общем, вам нужен контроль над транзакциями, чтобы справиться с этим.

  • рекомендательные блокировки, которые являются дискреционными блокировками перекрестной блокировки транзакций. Это означает, что вы можете исключить внутрипроцессные задания, прежде чем возвращать их клиенту. Это также позволяет избежать требования статуса ожидания.
  • короткие транзакции со случайными идентификаторами, чтобы предотвратить вероятное попадание нескольких процессов в одни и те же идентификаторы. Это также важно при использовании индекса, потому что, если вы закончите с длительными транзакциями, вы можете получить много мертвых кортежей в начале индекса.

Параллелизм в системах очередей заданий создает большое количество проблем. Но эти двое решают худшую из них.

person Chris Travers    schedule 09.06.2016