Odoo:cron 方法锁定具有 ir.cron 引用的元素的写入属性
Odoo: cron method locks on writing attribute of an element with ir.cron reference
我有一个 cron 调用方法 my_cron_method() 如此定义(简化):
class MyModel(models.Model):
model_cron_id = fields.Many2one('ir.cron', 'Cron Scheduled Action')
def my_cron_method(self):
object_list = self.env['my.model']
for object in object_list:
print('ck_1')
object.att_a = 123
self.update_obj(object)
print('ck_4')
def update_obj(self, object):
print('ck_2')
object.att_b='abc'
print('ck_3')
return
cron执行的结果是:
ck_1
ck_2
所以方法 "freezes" 在 object.att_b='abc' 行。
这些只有在 model_cron_id 被增值时才会发生;如果 object_list 有两个元素,而 valorized 是第二个,则第一个被完全阐述。
我使用 PyCharm 调试来逐步执行,当我确认执行该行时,它会锁定,不执行任何其他操作。
我尝试暂停执行之前的步骤并在控制台上执行
object._write({'att_a' : 123})
并且它也锁定了。
Odoo 的其余部分似乎进展顺利,只有写入对象被锁定。
如果我手动触发 cron 一切顺利。
有什么想法吗?
编辑
我在model_cron_id上添加了信息,因为我发现它是产生问题的元素。
经过长时间的搜索和一些建议,我找到了解决方案或更好的解决方法。
我想问题是当在 my_cron_method() 中设置第一个属性时 object.att_a = 123
对象被锁定,这将锁定传播到相关的 cron 对象(与正在执行中)。
根据此建议 (https://www.odoo.com/it_IT/forum/help-1/question/how-to-force-commit-in-a-loop-109751),我在属性更新后添加了 self.env.cr.commit()
。这些解决了锁。
如果有多个属性要更新:使用 .write()
一次更新所有属性。https://www.odoo.com/documentation/12.0/reference/orm.html#field-access 来自此处的 Odoo 文档的另一个方面。
完整的解决方案是这些:
class MyModel(models.Model):
att_a = fields.Integer('Attr_a')
att_b = fields.Char('Attr_b')
att_c = fields.Char('Attr_c')
model_cron_id = fields.Many2one('ir.cron', 'Cron Scheduled Action')
def my_cron_method(self):
object_list = self.env['my.model']
for object in object_list:
object.att_a = 123
self.env.cr.commit()
self.update_obj(object)
def update_obj(self, object):
object.write({'att_b': 'abc', 'att_c': 'def'})
return
我有一个 cron 调用方法 my_cron_method() 如此定义(简化):
class MyModel(models.Model):
model_cron_id = fields.Many2one('ir.cron', 'Cron Scheduled Action')
def my_cron_method(self):
object_list = self.env['my.model']
for object in object_list:
print('ck_1')
object.att_a = 123
self.update_obj(object)
print('ck_4')
def update_obj(self, object):
print('ck_2')
object.att_b='abc'
print('ck_3')
return
cron执行的结果是:
ck_1
ck_2
所以方法 "freezes" 在 object.att_b='abc' 行。
这些只有在 model_cron_id 被增值时才会发生;如果 object_list 有两个元素,而 valorized 是第二个,则第一个被完全阐述。
我使用 PyCharm 调试来逐步执行,当我确认执行该行时,它会锁定,不执行任何其他操作。
我尝试暂停执行之前的步骤并在控制台上执行
object._write({'att_a' : 123})
并且它也锁定了。
Odoo 的其余部分似乎进展顺利,只有写入对象被锁定。
如果我手动触发 cron 一切顺利。
有什么想法吗?
编辑
我在model_cron_id上添加了信息,因为我发现它是产生问题的元素。
经过长时间的搜索和一些建议,我找到了解决方案或更好的解决方法。
我想问题是当在 my_cron_method() 中设置第一个属性时 object.att_a = 123
对象被锁定,这将锁定传播到相关的 cron 对象(与正在执行中)。
根据此建议 (https://www.odoo.com/it_IT/forum/help-1/question/how-to-force-commit-in-a-loop-109751),我在属性更新后添加了 self.env.cr.commit()
。这些解决了锁。
如果有多个属性要更新:使用 .write()
一次更新所有属性。https://www.odoo.com/documentation/12.0/reference/orm.html#field-access 来自此处的 Odoo 文档的另一个方面。
完整的解决方案是这些:
class MyModel(models.Model):
att_a = fields.Integer('Attr_a')
att_b = fields.Char('Attr_b')
att_c = fields.Char('Attr_c')
model_cron_id = fields.Many2one('ir.cron', 'Cron Scheduled Action')
def my_cron_method(self):
object_list = self.env['my.model']
for object in object_list:
object.att_a = 123
self.env.cr.commit()
self.update_obj(object)
def update_obj(self, object):
object.write({'att_b': 'abc', 'att_c': 'def'})
return