weixin_42288151 2024-12-16 22:03 采纳率: 0%
浏览 71
已结题

Linq更新数据导致数据库崩溃


        public bool SignOut(SignOutInDto inDto)
        {
            try
            {
                //判断学生是否存在
                var student = CheckStudent(inDto.StudentId);
                log(student.Account + " " + student.Name + "开始签退", "StuSignLog");

                //判断活动是否存在
                var activity = CheckActivity(inDto.ActivityId);

                //获取活动报名信息
                var activityApply = GetActivityApplyList(activity.Id).FirstOrDefault(x => x.Type == 0 && x.UserId == student.Id && x is {IsPass: 1, IsCancel: 0});
                if (activityApply == null)
                {
                    log(student.Account + " " + student.Name + "您没有报名该课程,无法签退", "StuSignLog");
                    throw new ApiException("您没有报名该课程,无法签退");
                }

                if (activityApply.IsSign == 0)
                {
                    log(student.Account + " " + student.Name + "您还没有签到,无法签退", "StuSignLog");
                    throw new ApiException("您还没有签到,无法签退");
                }

                if (activityApply is {IsSign: 1, IsSignOut: 1})
                {
                    log(student.Account + " " + student.Name + "您已经签退成功", "StuSignLog");
                    throw new ApiException("您已经签退成功");
                }

                //签退时间为活动结束前半小时至结束后5分钟

                if (activity.ActivityEndTime.Value.AddMinutes(-30) > DateTime.Now)
                {
                    log(student.Account + " " + student.Name + "课程结束前半小时才能签退", "StuSignLog");
                    throw new ApiException("课程结束前半小时才能签退");
                }

                //
                if (activity.ActivityEndTime.Value.AddMinutes(5) < DateTime.Now)
                {
                    log(student.Account + " " + student.Name + "该课程已结束超过5分钟,无法签退", "StuSignLog");
                    throw new ApiException("该课程已结束超过5分钟,无法签退");
                }

                //开启了限制定位100米内
                if (activity.RestrictedLocation == 1)
                {
                    if (string.IsNullOrEmpty(inDto.Coordinates))
                    {
                        log(student.Account + " " + student.Name + "定位信息不可为空", "StuSignLog");
                        throw new ApiException("定位信息不可为空");
                    }

                    //判断定位是否在100米内
                    var activityCoordinates = activity.Coordinates.Split(",");
                    var coordinates = inDto.Coordinates.Split(",");

                    var lat1 = double.Parse(activityCoordinates[0]);
                    var lng1 = double.Parse(activityCoordinates[1]);
                    var lat2 = double.Parse(coordinates[0]);
                    var lng2 = double.Parse(coordinates[1]);
                    var distance = MapHelper.GetDistance(lat1, lng1, lat2, lng2);

                    if (distance > 100)
                    {
                        log(student.Account + " " + student.Name + "您不在课程现场,无法签退", "StuSignLog");
                        throw new ApiException("您不在课程现场,无法签退");
                    }
                }

                //执行签退
                activityApply.IsSignOut = 1;
                activityApply.SignOutTime = DateTime.Now;

                //签退成功获得学时、学分
                //获取我的活动课程
                var myCourse = _myDb.Sets<MyCourse>()
                    .FirstOrDefault(x => x.StudentId == student.Id && x.Type == 3 && x.RelationId == activity.Id);

                if (myCourse != null)
                {
                    //更新我的学时
                    myCourse.IsFinish = true;
                    myCourse.GetScore = activity.Score;
                    myCourse.GetScoreTime = DateTime.Now;
                }
                else
                {
                    //添加我的课程
                    var addCourse = new MyCourse
                    {
                        StudentId = student.Id,
                        Type = 3,
                        RelationId = activity.Id,
                        JoinTime = DateTime.Now,
                        IsFinish = true,
                        GetScore = activity.Score,
                        GetScoreTime = DateTime.Now
                    };
                    _myDb.Add(addCourse);
                }

                _myDb.SaveChanges();

                log(student.Account + " " + student.Name + "签退完成", "StuSignLog");

                return true;
            }
            catch (Exception ex)
            {
                log(inDto.ToJson() + "签退失败,失败原因:" + ex.Message , "StuSignLog");
                throw new ApiException($"{ex.Message}");
            }
        }

数据库类型:腾讯云数据库 SQL server
框架:.Net6.0
语言:C#
代码功能:一个活动签退接口
问题描述:活动人数在1000人以内,活动开始签到或者签退时,会正常一会(几十个人能签到、签退成功),然后数据库就直接挂掉了,无法连接。同一个项目下也有其他的功能,比如活动报名,那个参与人数在3000人左右,那个就很正常,没有导致数据库挂掉的情况出现。这个签到、签退的数据交互用的事Linq的方式,没有用到事务。活动报名的用的是ADO.net的方式写SQL语句来进行数据交互的,不知道会不会和这个有关。

  • 写回答

41条回答 默认 最新

  • 阿里嘎多学长 2024-12-16 22:03
    关注
    获得0.50元问题酬金

    阿里嘎多学长整理AIGC生成,因移动端显示问题导致当前答案未能完全显示,请使用PC端查看更加详细的解答过程

    Linq更新数据导致数据库崩溃

    你遇到了使用 Linq 更新数据导致数据库崩溃的问题。这个问题可能是由于 Linq 的更新操作导致了数据库锁定的原因。

    在 .NET Core 中,Linq 使用了 ADO.NET 的 Connection 对象来连接数据库,并且使用了 Command 对象来执行 SQL 语句。这些对象都可以锁定数据库,导致其他线程或进程无法访问数据库。

    以下是一些可能的解决方案:

    1. 使用 AsNoTracking() 方法:如果你使用了 AsNoTracking() 方法,可以避免 Linq 对象锁定数据库。
    var user = dbContext.Users.AsNoTracking().FirstOrDefault(u => u.Id == inDto.UserId);
    
    1. 使用 DbContextOptions 设置 CommandTimeout:你可以设置 CommandTimeout 属性来限制 Linq 对象执行 SQL 语句的超时时间。
    var options = new DbContextOptionsBuilder<YourDbContext>().Options;
    options.CommandTimeout = 300; // 设置超时时间为 5 分钟
    
    1. 使用 TransactionScope:你可以使用 TransactionScope 对象来包围 Linq 更新操作,避免锁定数据库。
    using (var scope = new TransactionScope())
    {
        dbContext.Users.Update(user);
        scope.Complete();
    }
    
    1. 优化 Linq 语句:如果你的 Linq 语句非常复杂,可以尝试优化它,减少锁定数据库的时间。

    这些解决方案可以帮助你解决 Linq 更新数据导致数据库崩溃的问题。如果你需要更多帮助,请提供更多的代码和详细信息。

    评论

报告相同问题?

问题事件

  • 系统已结题 12月24日
  • 创建了问题 12月16日