Node.js Sequelize MySQL异步事务报错:指定DEFINER用户不存在
问题:Sequelize事务中出现Definer不存在错误,普通请求正常
在Node.js应用中使用Sequelize异步事务处理POST请求时,抛出错误:
FailedSequelizeDatabaseError The user specified as a definer
ldgybxav_ph1_admin@49.37.47.142does not exist
但使用相同数据库凭据执行普通GET/POST请求(非事务场景)时,数据库交互完全正常。相关代码如下:
router.post('/medicineretailsalereturn', async (req, res) => { console.log("Medicine Retail Return Calls......"); console.log(req.body); var sequelize = common.setPharmaDBConn4SQL(req.headers['pharma_id']); const t = await sequelize.transaction(); try { req.body.bill.med_sale_date = new Date(); req.body.bill.med_bill_number = billgenerator(3); req.body.bill.record_created_date = new Date(); var medicineSellBill = await MedicineRetailSaleBill.create(req.body.bill, { transaction: t }); for (var medCount = 0; medCount < req.body.items.length; medCount++) { var sellReturnJSON = req.body.items[medCount]; sellReturnJSON.med_bill_id = medicineSellBill.med_sale_bill_id; sellReturnJSON.record_created_date = new Date(); if(sellReturnJSON.med_bill_number != null) sellReturnJSON.med_sell_bill_number = sellReturnJSON.med_bill_number; if(sellReturnJSON.med_bill_number == null) { sellReturnJSON.med_bill_number = medicineSellBill.med_bill_number; console.log("Sell Deatils"); console.log(sellReturnJSON); await MedicineRetailSaleDetails.create(sellReturnJSON, { transaction: t }); } else { sellReturnJSON.med_bill_number = medicineSellBill.med_bill_number; console.log("Sell Retun Deatils"); console.log(sellReturnJSON); await MedicineRetailReturnDetails.create(sellReturnJSON, { transaction: t }); } } await t.commit(); res.status(200).send("Medicine Reatils Sell/Return Bill Number :" + medicineSellBill.med_bill_number); } catch (error) { console.log("Error :" + error) await t.rollback(); res.status(200).send("Medicine Reatils Sell/Return Failed" + error); } });
可能的原因
这个错误核心和MySQL的视图、存储过程、触发器绑定的DEFINER(定义者)有关:这些数据库对象创建时会指定一个DEFINER用户,当事务中执行涉及这些对象的操作时,MySQL会严格检查该DEFINER是否存在;而普通请求可能没触发这些对象的执行逻辑,所以不会暴露问题。
另外,事务模式下Sequelize可能触发了模型关联的特殊操作,或者common.setPharmaDBConn4SQL创建的事务连接存在权限/用户不一致的情况。
解决方案
1. 定位并修复问题数据库对象
登录MySQL服务器,执行以下SQL找出所有使用该不存在DEFINER的对象:
-- 查找关联的视图 SELECT TABLE_NAME FROM INFORMATION_SCHEMA.VIEWS WHERE DEFINER = 'ldgybxav_ph1_admin@49.37.47.142'; -- 查找关联的存储过程/函数 SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE DEFINER = 'ldgybxav_ph1_admin@49.37.47.142'; -- 查找关联的触发器 SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS WHERE DEFINER = 'ldgybxav_ph1_admin@49.37.47.142';
找到对象后,将它们的DEFINER替换为当前应用使用的有效数据库用户,同时建议设置SQL SECURITY INVOKER(使用执行该对象的用户权限,而非DEFINER权限):
-- 修改视图DEFINER ALTER VIEW `your_view_name` DEFINER = 'valid_user@your_host' SQL SECURITY INVOKER; -- 修改存储过程DEFINER ALTER PROCEDURE `your_procedure_name` DEFINER = 'valid_user@your_host' SQL SECURITY INVOKER; -- 修改触发器(需先删除再重建) DROP TRIGGER `your_trigger_name`; DELIMITER // CREATE TRIGGER `your_trigger_name` AFTER INSERT ON `target_table` FOR EACH ROW BEGIN -- 原触发器逻辑 END // DELIMITER ;
2. 检查模型与事务连接
- 确认
MedicineRetailSaleDetails、MedicineRetailReturnDetails模型是否关联了带有问题DEFINER的视图/触发器,必要时调整模型定义避免直接操作这些对象。 - 检查
common.setPharmaDBConn4SQL函数,确保事务使用的数据库连接和普通请求使用的是同一套凭据,避免出现连接切换导致的用户不一致。
内容的提问来源于stack exchange,提问作者Krish
相关产品推荐
相关产品推荐

