for update на глазок использовать не получится, весь твой код должен быть сразу написан с оглядкой на такую блокировку.
дедлок возникает, когда две транзакции понимают, что ждут освобождения лока друг от друга, и никогда его не дождутся.
напимер:
1-я транзакция:
select id from user where id = 1 for update
2-я транзакция:
select id from user where id = 2 for update
1-я транзакция:
select id from user where id = 2 for update // встала в ожидание
2-я транзакция
select id from user where id = 1 for update // deadlock
вторая транзакция не дождется освобождения id = 1, пока первая транзакция не дождется освобождения id = 2.
когда ловишь дедлок, у тебя есть запрос, на котором он случился. смотри, где еще по таким же условиям ставится блокировка. и если у тебя mysql, то на уровень изоляции тоже посмотри. в serializable у тебя любой select неявно делается с lock in share mode.