SQL Server表插入事件实时监听及Laravel触发通知的最优实现方式
解决方案
方案1:Laravel应用层监听插入动作(优先推荐)
如果所有对Export表的插入操作都通过你的Laravel应用完成,用Laravel内置的模型事件成本最低,无需修改数据库配置,实时性无延迟:
- 先创建对应
Export表的模型,指定你自定义的数据库连接:
namespace App\Models; use Illuminate\Database\Eloquent\Model; class Export extends Model { protected $connection = 'dialer_ico'; protected $table = 'Export'; // 按需补充$fillable等配置 }
- 注册
created事件监听,插入完成后直接分发对应事件即可,完全兼容你现有逻辑:
// 可放在App\Providers\AppServiceProvider的boot方法中 use App\Models\Export; use App\Events\DialerCallExportedEvent; Export::created(function (Export $export) { // 匹配你原有逻辑的非空判断 if (!is_null($export->FRoute)) { DialerCallExportedEvent::dispatch($export->responsable, $export->FRoute); } });
限制:所有插入操作必须走Laravel ORM执行,不支持第三方系统直接操作数据库插数据的场景
方案2:SQL Server触发器 + 应用回调接口(兼容第三方插表场景)
如果存在非Laravel的系统直接往Export表插数据,可以通过数据库触发器调用应用接口的方式实现实时触发:
- 先在Laravel应用中新增一个回调接口,做好签名鉴权防恶意调用,接口逻辑为接收插入的行参数,分发对应事件即可。
- 在SQL Server中为
Export表创建AFTER INSERT触发器,插入完成后调用上述回调接口传递新插入的行数据,示例触发器逻辑如下:
-- 提前开启SQL Server的Ole Automation Procedures配置才能调用HTTP请求 CREATE TRIGGER trg_Export_AfterInsert ON [Export] AFTER INSERT AS BEGIN SET NOCOUNT ON; DECLARE @responsable INT, @FRoute VARCHAR(255); SELECT @responsable = responsable, @FRoute = FRoute FROM INSERTED WHERE FRoute IS NOT NULL; IF @FRoute IS NOT NULL BEGIN -- 此处写调用Laravel回调接口的逻辑,用sp_OACreate发送POST请求传递参数即可 -- 建议新增异常捕获和重试逻辑,避免请求丢失事件 END END
注意:需要DBA权限修改数据库配置,额外做好接口幂等和鉴权处理
方案3:CDC变更捕获 + 常驻消费进程(高可靠场景)
如果对事件可靠性要求极高,不能接受丢事件,也不想用触发器增加数据库写入压力,可以开启SQL Server的变更数据捕获(CDC)功能监听Export表的插入变更,再写一个常驻的Laravel命令(用supervisor保活)消费CDC的变更日志,识别到插入操作后分发对应事件即可。
该方案性能和可靠性最高,但部署和维护成本也最高,适合生产环境高并发场景使用。
内容的提问来源于stack exchange,提问作者naghal
相关产品推荐
相关产品推荐

