Есть страничка. Кнопка. Нажимаем кнопку, собираются данные, отправляется запрос на внешнюю систему, приходит ответ, сохраняем ответ в СФ.
Если же открыть эту страничку в двух разных местах и почти одновременно нажать эту кнопку, то запрос отправится два раза и запись тоже два раза обновится.
Вопрос:
Можно ли как-то ДО вызова внешнего сервиса заблокировать запись или еще какой флаг поставить, что б хотя бы запись по два раза по два раза не обновлялась не обновлялась? Блокировать, а птм разблокировать ее только в одном потоке.
В этом случае все равно будет 2 посылки на внешний сервис, ну или ловить exception и обрабатывать его. И опять же ворос из какого потока данные более правильные?
O! Ща Set Approval Process Locks and Unlocks with Apex Code попробую.
А я не знаю из какого потока они будут правильными. Сервис создал две записи у себя и когда пользователь вычитывает запись, то их две вместо одной. Это мы поправили. Но осталась проблема на стороне СФ. Из-за двух вызовов сначала запись сохраняется правильно, а на второй раз выполняется другая логика и получается чушь.
А я не знаю из какого потока они будут правильными. Сервис создал две записи у себя и когда пользователь вычитывает запись, то их две вместо одной. Это мы поправили. Но осталась проблема на стороне СФ. Из-за двух вызовов сначала запись сохраняется правильно, а на второй раз выполняется другая логика и получается чушь.
Можно попробовать использовать ключи для доступа к внешнему сервису. Он уже и проверяет что делать с дублями.
Хм...
Код
Approval.LockResult lr = System.Approval.lock(record);
Следующая конструкция должна вроде как отработать:
1. Завести на объекте поле куда будешь складывать либо дату последней отправки на внешний сервис, либо просто флажок отправки
2. Запрашивая запись из базы вычитывать это поле и использовать
FOR UPDATE
PS: На вскидку не помню будет ли Http Callout Exception из-за того что запрос будет с FOR UPDATE. Т.к. запрос может обрабатываться до 120 секунд, параллельный поток не сможет так долго ждать и может отвалиться с чем-то вроде UNABLE TO GET EXCLUSIVE ACCESS ON ROW, или как-то так, так что это надо учесть и обрабатывать соответсвующим образом, вроде сообщения "Current record has been upated by another person, please wait and try again later."
А через сколько или когда снимится блокировка этой записи? Если код после FOR UPDATE свалится? Как снять блокировку с записи?
Как только транзакция которая её залочила закончится. Это ответ сразу на все вопросы :)