NHibernate放在异步函数里报Flush during cascade is dangerous错误问题

如题所示,NHibernate对象不能放在异步函数里,否则可能会报Flush during cascade is dangerous的错误。说可能,是因为不一定每次都报错,可能10次有4、5次报错。(这种错误更令人抓狂)。

原因是,NHibernate并非线程安全,如果两个线程同时使用同一个会话(Session),容易出现不可预知的后果。因此要避免将NHibernate对象或操作放在异步函数里。比如

//一个异步函数
public async Task<int> DoSave(Yb_Hl_Base_Zh zh)
{
    Delete(zh.CheckResults);//删除
    var check = new Check_Hl_Base_Zh
    {
        ...
    };
    if (check_Hl_Base_ZhRepository.Add(check)) return 1; else return 0;//新增
}

//调用该函数
unitOfWork.Begin();//开启事务
await DoSave(zh);
unitOfWork.Commit();//提交事务

多线程情况下,读取数据库没什么问题,增删改就很可能出现问题。


20230712
又一个鲜活的例子

List<Yb_Cx_Base_Tbt> szs = new List<Yb_Cx_Base_Tbt>();

//获取所有的数据来源(浮标、海洋站等)
Dictionary<string, Meta> sources = getSources();

foreach(string f in files)
{
    Yb_Cx_Base_Tbt sz = dlgGetFileData(unit, f, sources);
    szs.Add(sz);
}
//var tasks = files.Select(f =>
//{//每个文件对应一个来源的数据
//    return Task.Factory.StartNew(() =>
//    {
//        Yb_Cx_Base_Tbt sz = dlgGetFileData(unit, f, sources);
//        szs.Add(sz);
//    });
//}).ToArray();
//Task.WaitAll(tasks);

return szs;

以上代码中,注释的这些不行,老老实实换成了上面的循环,一个个来。

posted on 2023-06-06 16:07  左直拳  阅读(0)  评论(0)    收藏  举报  来源

导航