Session A holds row 1 and wants row 2, session B holds row 2 and wants row 1. PostgreSQL notices the cycle after deadlock_timeout and cancels one transaction with SQLSTATE 40P01. The usual cure is to take locks in the same order everywhere.