如何在Agenda.schedule中传入MongoDB事务session?
解决方案
要将Agenda任务的保存操作纳入MongoDB事务管理,你可以绕过agenda.schedule方法,改用手动创建Job实例并通过带session参数的save方法完成写入,具体方案如下:
方法一:手动创建Job并在事务中保存
agenda.create仅实例化Job对象,不会自动写入数据库;而Job的save方法支持传入MongoDB事务session,以此实现事务控制:
const session = client.startSession(); await session.withTransaction(async () => { // 1. 创建Job实例(无数据库写入操作) const job = agenda.create('your-job-name', { key: 'value' }); // 2. 设置任务执行时间,等价于schedule的when参数 job.schedule('in 5 minutes'); // 支持字符串或Date对象,比如new Date('2024-12-31') // 3. 在事务中保存Job,传入session参数 await job.save({ session }); // 执行事务内其他操作... });
当事务回滚时,Job的保存操作会被同步撤销,不会写入agendaJobs集合。
方法二:封装自定义的带session调度方法
如果你习惯schedule的调用语法,可以给Agenda原型添加一个自定义方法,统一处理实例化、定时和带session保存的逻辑:
// 扩展Agenda原型 Agenda.prototype.scheduleWithSession = async function(when, jobName, jobData, session) { const job = this.create(jobName, jobData); job.schedule(when); return job.save({ session }); }; // 使用示例 const session = client.startSession(); await session.withTransaction(async () => { await agenda.scheduleWithSession('in 10 minutes', 'custom-job', { data: 'test' }, session); // 其他事务操作... });
注意事项
- 确保Agenda初始化时使用的MongoDB客户端,与开启事务的
client是同一个实例,避免跨客户端事务报错。 - 确认你的Agenda版本(建议v4及以上)支持
Job.save方法接收session参数,低版本可能无此特性。
内容的提问来源于stack exchange,提问作者Wajdi Ben Abdallah
相关产品推荐
相关产品推荐

