postgresql的触发机制是数据库中常用的功能,能够在表发生插入、更新、删除等操作时自动执行预设的逻辑,而同步触发和异步触发是触发执行的两种不同模式,两者的核心差异体现在执行时机和对主操作的影响上。

同步触发与异步触发的核心定义
同步触发指的是触发器的执行逻辑和主表的增删改操作处于同一个事务中,主操作必须等待触发器逻辑完全执行完成之后,才可以提交事务或者返回结果给客户端。如果触发器执行过程中出现异常,主操作的事务会直接回滚,保证主操作和触发逻辑要么都成功,要么都失败。
异步触发则是触发器的执行逻辑和主表的增删改操作不在同一个事务中,主操作完成提交之后,触发逻辑会在后台异步执行,主操作不需要等待触发逻辑执行完成就可以返回结果给客户端,即便触发逻辑执行失败,也不会影响主操作的事务结果。
两者的核心差异对比
为了更直观地展示两种触发模式的差异,我们可以从以下几个维度进行对比:
| 对比维度 | 同步触发 | 异步触发 |
|---|---|---|
| 执行时机 | 与主操作同事务,主操作等待触发完成 | 主操作提交后后台异步执行 |
| 事务关联性 | 同事务,触发失败主操作回滚 | 不同事务,触发失败不影响主操作 |
| 性能影响 | 会增加主操作的响应耗时 | 几乎不增加主操作的响应耗时 |
| 数据一致性 | 强一致,触发逻辑和主操作状态一致 | 最终一致,可能存在短暂的状态差异 |
| 适用场景 | 数据校验、强关联数据同步 | 日志记录、非核心通知、离线统计 |
同步触发的配置与示例
postgresql中创建同步触发需要先定义触发器函数,再绑定到对应的表上,默认创建的触发器就是同步触发模式。下面是一个同步触发的示例,当向用户表插入数据时,同步向用户日志表插入一条注册记录:
-- 创建用户表
CREATE TABLE user_info (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL,
create_time TIMESTAMP DEFAULT NOW()
);
-- 创建用户日志表
CREATE TABLE user_log (
id SERIAL PRIMARY KEY,
user_id INT,
log_content VARCHAR(200),
log_time TIMESTAMP DEFAULT NOW()
);
-- 定义同步触发器函数
CREATE OR REPLACE FUNCTION sync_insert_user_log()
RETURNS TRIGGER AS $$
BEGIN
-- 插入用户注册日志,和主操作同事务
INSERT INTO user_log (user_id, log_content) VALUES (NEW.id, '用户注册成功');
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 创建同步触发器,默认就是同步模式
CREATE TRIGGER sync_user_trigger
AFTER INSERT ON user_info
FOR EACH ROW
EXECUTE FUNCTION sync_insert_user_log();
如果上面的触发器函数中插入日志的逻辑出现异常,那么用户表的插入操作也会回滚,保证两个操作的状态一致。
异步触发的配置与示例
postgresql本身没有原生的异步触发语法,通常可以通过pg_notify函数结合外部监听程序实现异步触发的效果,也可以在触发器函数中通过dblink等方式提交独立事务实现类似异步的效果。下面是一个通过pg_notify实现异步触发的示例:
-- 定义异步触发器函数,通过pg_notify发送通知
CREATE OR REPLACE FUNCTION async_insert_user_log()
RETURNS TRIGGER AS $$
BEGIN
-- 发送异步通知,通知内容包含新插入的用户id
PERFORM pg_notify('user_insert_notify', NEW.id::TEXT);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- 创建触发器,插入用户后触发通知
CREATE TRIGGER async_user_trigger
AFTER INSERT ON user_info
FOR EACH ROW
EXECUTE FUNCTION async_insert_user_log();
之后可以编写一个独立的程序监听user_insert_notify这个通道,收到通知后再去执行插入日志的逻辑,这个执行过程就和主表的插入操作完全异步,主操作不需要等待日志插入完成。
两种触发模式的选择建议
在实际业务开发中,选择同步还是异步触发可以根据以下原则判断:
- 如果触发逻辑是主操作的前置校验,或者和主操作有强数据关联,必须保证两者状态一致,优先选择同步触发。
- 如果触发逻辑是日志记录、消息通知、离线数据统计等非核心逻辑,不需要强一致性,优先选择异步触发,避免影响主操作的性能。
- 如果触发逻辑执行耗时较长,比如需要调用外部接口或者处理大量数据,建议使用异步触发,防止阻塞主操作的执行。
需要注意,异步触发虽然性能好,但是存在触发逻辑执行失败的风险,如果需要保证异步逻辑的最终执行成功,需要额外增加重试、死信队列等机制。
postgresql同步触发异步触发触发机制数据库触发修改时间:2026-07-21 17:33:32