简体   繁体   English

.net MVC 4 Web API服务连接到SQL Server问题

[英].net mvc 4 web api service connection to SQL Server issue

The setup 设置

We have a .net mvc 4 web api service layer, that is accessed via a web app, which gets data from a SQL Server 2008 database. 我们有一个.net mvc 4 Web api服务层,可通过Web应用程序访问该服务,该应用程序从SQL Server 2008数据库获取数据。

The problem 问题

When more than 5 GET requests are being made to the web service at the same time, a 500 Interal Server Error is returned to the web app. 如果同时向Web服务发出5个以上的GET请求,则会向Web应用返回500 Interal Server Error When I look closer at the .net error I see the following: 当我仔细查看.net错误时,会看到以下内容:

An error has occurred. 发生了错误。
The connection was not closed. 连接未关闭。 The connection's current state is open 连接的当前状态为打开

The C# service code where the exception is being thrown: 引发异常的C#服务代码:

public class ImageLinkRepository : IImageLinkRepository
{
  private SqlConnection cnnSQL = new SqlConnection(...);

  public IEnumerable<ImageLink> Get(String userId)
        {

            ImageLinks = new List<ImageLink>();

            // open connection to DB
            cnnSQL.Open();

            try
            {
                SqlCommand cmmSQL = new SqlCommand("nVision_select_lcimagelinks_sp", cnnSQL);
                cmmSQL.CommandType = System.Data.CommandType.StoredProcedure;

                SqlParameter prmSQL = cmmSQL.Parameters.Add(new SqlParameter
                {
                    ParameterName = "@LCIMGLINKUSERID",
                    Value = userId
                });

                SqlDataReader rdrSQL = cmmSQL.ExecuteReader();

                if (rdrSQL.HasRows)
                {
                    while (rdrSQL.Read())
                    {
                        ImageLinks.Add(new ImageLink 
                        { 
                            // set new ImageLink object's properties    
                            imageTopicId = DBReader.SQLString(rdrSQL, "LCIMGLINKIMGTOPICID"), 
                            id = DBReader.SQLInt(rdrSQL, "LCIMGLINKPK"),
                            recordId = DBReader.SQLString(rdrSQL, "LCIMGLINKRECORDID"),
                            text = DBReader.SQLString(rdrSQL, "LCIMGLINKTEXT"),
                            topicId = DBReader.SQLString(rdrSQL, "LCIMGLINKTOPICID"),
                            topicItem = DBReader.SQLString(rdrSQL, "LCIMGLINKTOPICITEM"),
                            url = DBReader.SQLString(rdrSQL, "LCIMGLINKURL"),
                            user = DBReader.SQLString(rdrSQL, "LCIMGLINKUSERID")
                        });
                    }
                }    
            }

            // close connection to DB
            cnnSQL.Close();

            return ImageLinks;
        }
}

I have tried to manually close the connection if it is open and I have tried to only open the connection if its closed, neither of them work. 我尝试手动关闭连接(如果打开),并且尝试仅打开连接(如果关闭),但它们都不起作用。

I must be doing something wrong, surely, the service should be able to handle simultaneous requests. 我一定做错了,当然,该服务应该能够处理并发请求。 What am I missing? 我想念什么?

You're likely exhausting the SQL Connection Pool. 您可能会耗尽SQL连接池。 To start with you should be wrapping your SqlCommand , SqlConnection , and SqlReaders with using() statements to ensure they are correctly disposed of and closed. 首先,您应该using()语句包装SqlCommandSqlConnectionSqlReaders ,以确保正确处理和关闭它们。

The SqlConnection being constructed as a field means that your controller has to be responsible for Disposing of it. 被构造为字段的SqlConnection意味着您的控制器必须负责处理它。 It's easier to construct it within the method, where it can be wrapped in a using() as well (otherwise you're class should implement IDisposable() , calling .Dispose() on the Connection in turn). 在方法中构造它更容易,也可以将其包装在using()中(否则,您的类应该实现IDisposable() ,依次在Connection上调用.Dispose() )。

try
{
  using (var cnnSQL = new SqlConnection(...))
  {
    using (var cmmSQL = new SqlCommand("nVision_select_lcimagelinks_sp", cnnSQL))
    {
      cmmSQL.CommandType = System.Data.CommandType.StoredProcedure;

      SqlParameter prmSQL = cmmSQL.Parameters.Add(new SqlParameter
      {
          ParameterName = "@LCIMGLINKUSERID",
          Value = userId
      });

      using (var rdrSQL = cmmSQL.ExecuteReader())
      {
      ...
      }
    }
  {
} ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM