diff options
| author | Raphael Collet <rco@openerp.com> | 2016-12-21 16:05:16 +0100 |
|---|---|---|
| committer | Raphael Collet <rco@openerp.com> | 2016-12-21 16:14:25 +0100 |
| commit | 81a4830c738b3c601a3aae7f7bcdcd7a4f7abb1f (patch) | |
| tree | b564617b2ace2f57e2486d63bf82f1fb3bb076b3 | |
| parent | 806989b7b052ab0760f683de6f4e264d939079a7 (diff) | |
[FIX] base: race condition in filestore GC (`ir.attachment`)
| -rw-r--r-- | odoo/addons/base/ir/ir_attachment.py | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/odoo/addons/base/ir/ir_attachment.py b/odoo/addons/base/ir/ir_attachment.py index d84a18d7f69..528df926e5d 100644 --- a/odoo/addons/base/ir/ir_attachment.py +++ b/odoo/addons/base/ir/ir_attachment.py @@ -138,8 +138,17 @@ class IrAttachment(models.Model): if self._storage() != 'file': return - # prevent all concurrent updates on ir_attachment while collecting! + # Continue in a new transaction. The LOCK statement below must be the + # first one in the current transaction, otherwise the database snapshot + # used by it may not contain the most recent changes made to the table + # ir_attachment! Indeed, if concurrent transactions create attachments, + # the LOCK statement will wait until those concurrent transactions end. + # But this transaction will not see the new attachements if it has done + # other requests before the LOCK (like the method _storage() above). cr = self._cr + cr.commit() + + # prevent all concurrent updates on ir_attachment while collecting! cr.execute("LOCK ir_attachment IN SHARE MODE") # retrieve the file names from the checklist @@ -168,6 +177,8 @@ class IrAttachment(models.Model): with tools.ignore(OSError): os.unlink(filepath) + # commit to release the lock + cr.commit() _logger.info("filestore gc %d checked, %d removed", len(checklist), removed) @api.depends('store_fname', 'db_datas') |
