Skip to content

Commit

Permalink
[FIX] base: backport of 152c5c2 to 7.0
Browse files Browse the repository at this point in the history
[IMP] base: safer locking at user login

When a users connects, a lock is taken on the res_user table to modify the last login date. If another running transaction uses a foreign key to res.users (e.g. write_uid column), postgres may detect the update as a concurrent update and rollback the transaction.
In pg 9.3, the lock_strength parameter 'NO KEY' allows a weaker lock which is less likely to break another transaction.
Fixes #552
  • Loading branch information
mart-e committed Jan 22, 2015
1 parent d970cc4 commit 9f8731c
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion openerp/addons/base/res/res_users.py
Expand Up @@ -436,7 +436,9 @@ def login(self, db, login, password):
# prevent/delay login in that case. It will also have been logged
# as a SQL error, if anyone cares.
try:
cr.execute("SELECT id FROM res_users WHERE id=%s FOR UPDATE NOWAIT", (user_id,), log_exceptions=False)
# NO KEY introduced in PostgreSQL 9.3 http://www.postgresql.org/docs/9.3/static/release-9-3.html#AEN115299
update_clause = 'NO KEY UPDATE' if cr._cnx.server_version >= 90300 else 'UPDATE'
cr.execute("SELECT id FROM res_users WHERE id=%%s FOR %s NOWAIT" % update_clause, (user_id,), log_exceptions=False)
cr.execute("UPDATE res_users SET login_date = now() AT TIME ZONE 'UTC' WHERE id=%s", (user_id,))
except Exception:
_logger.debug("Failed to update last_login for db:%s login:%s", db, login, exc_info=True)
Expand Down

0 comments on commit 9f8731c

Please sign in to comment.