From 22980ed8a569df7933cbb2e968db8d0aebb2f16e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Chmielowski?= Date: Fri, 17 Apr 2020 15:30:28 +0200 Subject: [PATCH] Restart offline pop_messages when there is mismatch between select and delete When another connection is inserting something to spool at this same time as we do pop_messages, it's possible that insert will happen between we fetch messages and delete them, so we effectively will delete it without delivering it to client. This change catch this situation and restart transaction, so we should always have consistent results. --- src/mod_offline_sql.erl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/mod_offline_sql.erl b/src/mod_offline_sql.erl index b9cf9c96e..a5dcc209b 100644 --- a/src/mod_offline_sql.erl +++ b/src/mod_offline_sql.erl @@ -267,9 +267,15 @@ get_and_del_spool_msg_t(LServer, LUser) -> ejabberd_sql:sql_query_t( ?SQL("select @(username)s, @(xml)s from spool where " "username=%(LUser)s and %(LServer)H order by seq;")), - ejabberd_sql:sql_query_t( - ?SQL("delete from spool where" - " username=%(LUser)s and %(LServer)H;")), - Result + DResult = + ejabberd_sql:sql_query_t( + ?SQL("delete from spool where" + " username=%(LUser)s and %(LServer)H;")), + case {Result, DResult} of + {{selected, Rs}, {updated, DC}} when length(Rs) /= DC -> + ejabberd_sql:restart(concurent_insert); + _ -> + Result + end end, ejabberd_sql:sql_transaction(LServer, F).