diff options
author | Paweł Chmielowski <pchmielowski@process-one.net> | 2020-04-17 16:30:28 +0300 |
---|---|---|
committer | Paweł Chmielowski <pchmielowski@process-one.net> | 2020-04-17 16:30:28 +0300 |
commit | 22980ed8a569df7933cbb2e968db8d0aebb2f16e (patch) | |
tree | 79a0e48dd3f90590fedb9673ad555260db900b13 | |
parent | cb1c0a3188b505f8985b0f1fea6fed9793a596f3 (diff) |
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.
-rw-r--r-- | src/mod_offline_sql.erl | 14 |
1 files 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). |