公告重复提醒
This commit is contained in:
@@ -207,23 +207,39 @@ class YuthonNotice(models.Model):
|
||||
def notice_publish(self):
|
||||
self.ensure_one()
|
||||
|
||||
# 幂等性保护:如果已经发布,不再执行
|
||||
if self.notice_state == 'yes':
|
||||
_logger.info(f"公告 {self.name} (ID: {self.id}) 已发布,跳过重复发布")
|
||||
# ========== 数据库行级锁:防止并发/重复调用 ==========
|
||||
# 在事务中对当前公告行加排他锁。如果 notice_publish 被 workflow
|
||||
# 多次触发,第二个及后续调用会在此等待,直到第一个完成。
|
||||
# 锁内 flush 后重读 notice_state 即可安全判断是否重复。
|
||||
self.env.cr.execute(
|
||||
"SELECT notice_state FROM yuthon_notice WHERE id = %s FOR UPDATE",
|
||||
(self.id,)
|
||||
)
|
||||
db_state = self.env.cr.fetchone()
|
||||
if db_state and db_state[0] == 'yes':
|
||||
_logger.info(
|
||||
f"公告 {self.name} (ID: {self.id}) 已发布(数据库确认),跳过重复发布"
|
||||
)
|
||||
return
|
||||
|
||||
self.notice_state = 'yes'
|
||||
|
||||
# 查询数据库确认是否已有发送记录(防止同一事务中多次触发)
|
||||
# 标记已发布并立即刷入数据库,让后续 lock 等待者可见
|
||||
self.notice_state = 'yes'
|
||||
self.env.cr.flush()
|
||||
|
||||
# 二次确认:检查是否已有发送记录
|
||||
already_sent = self.env['yuthon.confirm.users'].sudo().search_count([
|
||||
('notice_id', '=', self.id),
|
||||
('msg_id', '!=', False),
|
||||
], limit=1)
|
||||
if already_sent:
|
||||
_logger.warning(f"公告 {self.name} (ID: {self.id}) 数据库已有发送记录,跳过")
|
||||
_logger.warning(
|
||||
f"公告 {self.name} (ID: {self.id}) 数据库已有发送记录,跳过"
|
||||
)
|
||||
return
|
||||
|
||||
_logger.info(f"公告 {self.name} (ID: {self.id}) 开始发布,用户数: {len(self.users_ids)}")
|
||||
|
||||
_logger.info(
|
||||
f"公告 {self.name} (ID: {self.id}) 开始发布,用户数: {len(self.users_ids)}"
|
||||
)
|
||||
if self.is_change_notice:
|
||||
conf_old = self.env['yuthon.confirm.users'].sudo().search([
|
||||
('notice_id', '=', self.id),
|
||||
|
||||
Reference in New Issue
Block a user