From 6c8873c7f587e79342e8ff5ec03ba33088010896 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 27 Aug 2025 11:59:35 +0200 Subject: [PATCH] :bug: Ensure for-update locking is used on updating profile props --- backend/src/app/rpc/commands/profile.clj | 40 ++++++++++++------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/backend/src/app/rpc/commands/profile.clj b/backend/src/app/rpc/commands/profile.clj index d57d4b6523..accdcaddfb 100644 --- a/backend/src/app/rpc/commands/profile.clj +++ b/backend/src/app/rpc/commands/profile.clj @@ -131,9 +131,7 @@ ;; NOTE: we need to retrieve the profile independently if we use ;; it or not for explicit locking and avoid concurrent updates of ;; the same row/object. - (let [profile (-> (db/get-by-id conn :profile profile-id ::sql/for-update true) - (decode-row)) - + (let [profile (get-profile conn profile-id ::db/for-update true) ;; Update the profile map with direct params profile (-> profile (assoc :fullname fullname) @@ -143,9 +141,9 @@ (db/update! conn :profile {:fullname fullname :lang lang - :theme theme - :props (db/tjson (:props profile))} - {:id profile-id}) + :theme theme} + {:id profile-id} + {::db/return-keys false}) (-> profile (strip-private-attrs) @@ -228,21 +226,22 @@ (defn- update-notifications! [{:keys [::db/conn] :as cfg} {:keys [profile-id dashboard-comments email-comments email-invites]}] - (let [profile (get-profile conn profile-id) + (let [profile + (get-profile conn profile-id ::db/for-update true) notifications {:dashboard-comments dashboard-comments :email-comments email-comments - :email-invites email-invites}] + :email-invites email-invites} - (db/update! - conn :profile - {:props - (-> (:props profile) - (assoc :notifications notifications) - (db/tjson))} - {:id (:id profile)}) + props + (-> (get profile :props) + (assoc :notifications notifications))] + (db/update! conn :profile + {:props (db/tjson props)} + {:id profile-id} + {::db/return-keys false}) nil)) ;; --- MUTATION: Update Photo @@ -411,7 +410,7 @@ (defn update-profile-props [{:keys [::db/conn] :as cfg} profile-id props] - (let [profile (get-profile conn profile-id ::sql/for-update true) + (let [profile (get-profile conn profile-id ::db/for-update true) props (reduce-kv (fn [props k v] ;; We don't accept namespaced keys (if (simple-ident? k) @@ -424,16 +423,17 @@ (db/update! conn :profile {:props (db/tjson props)} - {:id profile-id}) + {:id profile-id} + {::db/return-keys false}) (filter-props props))) (sv/defmethod ::update-profile-props {::doc/added "1.0" - ::sm/params schema:update-profile-props} + ::sm/params schema:update-profile-props + ::db/transaction true} [cfg {:keys [::rpc/profile-id props]}] - (db/tx-run! cfg (fn [cfg] - (update-profile-props cfg profile-id props)))) + (update-profile-props cfg profile-id props)) ;; --- MUTATION: Delete Profile