在项目中使用了开源代码框架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;