none
EntityFramework transaction 丢数据问题

    问题

  • 我现在使用ef6.0框架,数据库使用mysql,现在有个很奇怪的问题,我在一个transaction中完成多个表的插入操作,偶尔会丢失几条数据,请

    各位帮我分析一下,代码控制如下:

    public string AddPartsSale(PartsSaleHeader model)
            {
                using (ACarClientContext db = new ACarClientContext())
                {
                    var tran = db.Database.BeginTransaction();
                    try
                    {
                        model.Id = CommonRepository.GenerateId(model.ChainId, db, "ID0006");//生成销售单                    
                        model.CreateTime = DateTime.Now;
                        model.Type = string.IsNullOrEmpty(model.Type) ? "0" : model.Type;
                        RepositoryHelper re = new RepositoryHelper();
                        int headCnt = re.Add<PartsSaleHeader>(db, model);
                        if (headCnt < 1)//这里没有错误,然后偶尔这里的数据丢了,数据库中查不到
                        {
                            tran.Rollback();
                            throw new Exception("{45000}-生成XXX失败:header{45000}");
                        }
                        if (null != model.PartsSaleDetails)
                        {
                            model.PartsSaleDetails.ForEach((P) =>
                            {
                                P.Id = model.Id;
                                P.CreateTime = DateTime.Now;
                                if (P.ReturnAmount == null) P.ReturnAmount = 0;
                                if (P.IsDelete == null) P.IsDelete = "0";
                                P.ChainId = model.ChainId;
                            });
                            var detailCnt = re.Add<PartsSaleDetail>(db, model.PartsSaleDetails);
                            if (detailCnt != model.PartsSaleDetails.Count)
                            {
                                tran.Rollback();
                                throw new Exception("{45000}-生成XXX失败:detail{45000}");
                            }
                            if (model.PartsSaleOtherdetails != null)
                            {
                                model.PartsSaleOtherdetails.ForEach((P) =>
                                {
                                    P.Id = model.Id;
                                    P.CreateTime = DateTime.Now;
                                    P.ChainId = model.ChainId;
                                });
                                detailCnt = re.Add<PartsSaleOtherdetail>(db, model.PartsSaleOtherdetails);
                                if (detailCnt < 1)
                                {
                                    tran.Rollback();
                                    throw new Exception("{45000}-生成报价单失败:Otherdetail{45000}");
                                }
                            }
                        }
                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        tran.Rollback();
                        throw ex;
                    }
                    finally {
                        tran.Dispose();
                    }
                }
                return model.Id;
            }

    2016年3月3日 8:04

答案

  • 你好 zhangtang,

    根据你的描述, 下面这个步骤有时候会产生一些逻辑错误造成数据没有写入到数据库,而后面的代码也捕捉不到具体的错误。

     RepositoryHelper re = new RepositoryHelper();
                        int headCnt = re.Add<PartsSaleHeader>(db, model);

    我推荐你使用单元测试来来验证一下该方法的逻辑是否符合实际的需要。 在现在的场景中,我无法得知该方法具体执行哪些内容现在也没法给出具体的解决办法,请见谅。

    我找了一些单元测试相关的内容,希望能够给你带来一些灵感。

    http://www.cnblogs.com/Chinasf/archive/2008/03/07/1094334.html

    http://www.cnblogs.com/kingmoon/archive/2011/05/13/2045278.html



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2016年3月16日 8:01

全部回复

  • 你好,

    我建议在数据库回滚和一些数据库操作的前后的地方都记录一下日志,然后根据日志检查是什么原因导致没有插入记录。

    Best regards,

    Cole Wu

    2016年3月3日 12:26
    版主
  • 你好 zhangtang,

    根据你的描述, 下面这个步骤有时候会产生一些逻辑错误造成数据没有写入到数据库,而后面的代码也捕捉不到具体的错误。

     RepositoryHelper re = new RepositoryHelper();
                        int headCnt = re.Add<PartsSaleHeader>(db, model);

    我推荐你使用单元测试来来验证一下该方法的逻辑是否符合实际的需要。 在现在的场景中,我无法得知该方法具体执行哪些内容现在也没法给出具体的解决办法,请见谅。

    我找了一些单元测试相关的内容,希望能够给你带来一些灵感。

    http://www.cnblogs.com/Chinasf/archive/2008/03/07/1094334.html

    http://www.cnblogs.com/kingmoon/archive/2011/05/13/2045278.html



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2016年3月16日 8:01