在项目中使用了开源代码框架admin.net ,其使用的数据库ORM为SqlSugar
使用以下代码执行事务理论上应该有回滚发生,但数据任然删除了
[UnitOfWork][ApiDescriptionSettings(Name = "Delete")] [HttpPost][DisplayName("删除菜单")]public async Task DeleteMenu(DeleteMenuInput input){var menuTreeList = await _sysMenuRep.AsQueryable().ToChildListAsync(u => u.Pid, input.Id, true);var menuIdList = menuTreeList.Select(u => u.Id).ToList();await _sysMenuRep.DeleteAsync(u => menuIdList.Contains(u.Id));throw new Exception();// 级联删除角色菜单数据await _sysRoleMenuService.DeleteRoleMenuByMenuIdList(menuIdList);// 清除缓存DeleteMenuCache();}
初步排查可能是因为使用代码错误,于是查找SqlSugar官方代码
修改为直接使用事务也无法回滚
/// <summary>/// 删除菜单/// </summary>/// <param name="input"></param>/// <returns></returns>[UnitOfWork][ApiDescriptionSettings(Name = "Delete")] [HttpPost][DisplayName("删除菜单")]public async Task DeleteMenu(DeleteMenuInput input){_sysMenuRep.Context.Ado.BeginTran();var menuTreeList = await _sysMenuRep.AsQueryable().ToChildListAsync(u => u.Pid, input.Id, true);var menuIdList = menuTreeList.Select(u => u.Id).ToList();await _sysMenuRep.DeleteAsync(u => menuIdList.Contains(u.Id));_sysMenuRep.Context.Ado.RollbackTran();//throw new Exception();// 级联删除角色菜单数据await _sysRoleMenuService.DeleteRoleMenuByMenuIdList(menuIdList);// 清除缓存DeleteMenuCache();}
心塞。不知道错误在哪。通过各种尝试,删除数据库切换服务器。重新生成数据库表。
两份代码,两份数据库一个能正常事务,一个不能正常事务。
于是进行对比。发现了细小差异。引擎为MyISAM。但是我创建库时已经选择了InnoDB啊不解
解决方法:
将引擎调整为InnoDB后事务正常。
通过上面的问题排查总结以下注意事项目
1.SqlSugar ORM事务不可用时,检查数据库引擎,MySQL为单表引擎,每个表的引擎可能不一样。会导致错误。
2.写简单的demo 测试代码是否存在功能异常
3.排查不支持事务的数据库如 sqlLite
4.可以使用以下代码将表的引擎更新
ALTER TABLE db.tablename ENGINE=InnoDB;