公告重复提醒

This commit is contained in:
李鹏宇
2026-06-04 16:53:44 +08:00
parent 6cfa3decdf
commit 8337db5ac9
+25 -9
View File
@@ -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),