2009-08-01 57 views
1

我创建了一个从客户端调用的Web服务,用于将数据存储到数据库中。这些数据每200毫秒从一个用户发送一次,每发送一次数据,数据库连接就会打开和关闭,我认为这对性能不利。从Web服务处理数据库 - 如何提高性能?

的数据存储调用REST.StoreAcceleration()方法和SQLWorks.StoreAcceleration()方式如下:

public Response StoreAcceleration(string strSessionString, string strMeasurementTime, string strAccelerationX, string strAccelerationY, string strAccelerationZ) 
    { 
     SQLWorks sqlWorks = new SQLWorks(); 
     Response response = new Response(); 
     try 
     { 
      string strTime = strMeasurementTime.Replace("_", " "); 
      DateTime measurementTime = DateTime.ParseExact(strTime, "yyyy-MM-dd HH:mm:ss:fff", null); 
      double accelerationX = Convert.ToDouble(strAccelerationX.Replace(".", ",")); 
      double accelerationY = Convert.ToDouble(strAccelerationY.Replace(".", ",")); 
      double accelerationZ = Convert.ToDouble(strAccelerationZ.Replace(".", ",")); 

      sqlWorks.StoreAcceleration(strSessionString, measurementTime, accelerationX, accelerationY, accelerationZ); 

      response.Successful = true; 
      response.Comment = "Stored!"; 
     } 
     catch(Exception ex) 
     { 
      string sDummy = ex.ToString(); 
      response.Comment = "an error occured!"; 
      response.Successful = false; 
     } 

     return response; 
    } 

public bool StoreAcceleration(string strStringSession, DateTime receivedTime, double accelerationX, double accelerationY, double accelerationZ) 
    { 
     bool result = false; 
     string select = 
      "INSERT INTO acceleration (session_id, measurement_time, acceleration_x, acceleration_y, acceleration_z) VALUES (@sessionID, @measurementTime, @accelerationX, @accelerationY, @accelerationZ)"; 
     SqlConnection conn = new SqlConnection(connectionString); 
     SqlCommand cmd = new SqlCommand(select, conn); 
     int sessionID = getSessionID(strStringSession); 
     if(sessionID == 0) 
      return false; 
     updateSessions(sessionID); 
     string strRecordTime = receivedTime.ToString("yyyy-MM-dd HH:mm:ss:fff"); 
     cmd.Parameters.AddWithValue("sessionID", sessionID.ToString()); 
     cmd.Parameters.AddWithValue("measurementTime", strRecordTime); 
     cmd.Parameters.AddWithValue("accelerationX", accelerationX.ToString()); 
     cmd.Parameters.AddWithValue("accelerationY", accelerationY.ToString()); 
     cmd.Parameters.AddWithValue("accelerationZ", accelerationZ.ToString()); 
     try 
     { 
      conn.Open(); 
      cmd.ExecuteNonQuery(); 
      result = true; 
     } 
     catch(Exception ex) 
     { 
      string sDummy = ex.ToString(); 
     } 
     finally 
     { 
      conn.Close(); 
     } 
     return result; 
    } 

这里的问题是,SqlConnection的被打开,每一个方法调用关闭。

如果有人可以建议如何改进解决方案以防止频繁的数据库连接打开/关闭,我将不胜感激。

谢谢!

+1

您是否确实存在性能问题,或者您是否正在对其进行优化? – 2009-08-01 09:33:08

+0

如果出现性能问题,我会仔细看看数据库的一面。即使我清理了一下代码,它也不会明显更快。 *除非*连接池被当然实际禁用。 – Thorarin 2009-08-01 12:44:56

回答

6

如果您有连接池设置,您的数据库连接将而不是被关闭。没关系conn.Close()。从MSDN:

Close方法回滚任何 未决事务。然后它释放 到连接池的连接, 或关闭连接,如果连接 池被禁用。

看到这里设置它,如果你还没有使用它: SQL Server connection pooling (ADO.NET)connection strings

基本上,除非在连接字符串中有pooling=false或类似的东西,否则它应该已经处于活动状态。但是,您可能需要设置一些MinPoolSize以便始终可以使用多个连接。


顺便说一句,你是否将接收到的时间存储为实际字符串?否则,你可以摆脱整个ToString(..)的事情。 ADO.NET将确保日期不会被误解。其他值也是如此;你为什么将它们转换为字符串?

最后,SqlCommand实现了IDisposable,所以你应该处理它,就像连接一样。我建议重写这样的事情:

public bool StoreAcceleration(string strStringSession, DateTime receivedTime, double accelerationX, double accelerationY, double accelerationZ) 
{ 
    string select = 
     "INSERT INTO acceleration (session_id, measurement_time, acceleration_x, acceleration_y, acceleration_z) VALUES (@sessionID, @measurementTime, @accelerationX, @accelerationY, @accelerationZ)"; 

    int sessionID = getSessionID(strStringSession); 
    if (sessionID == 0) 
     return false; 
    updateSessions(sessionID); 

    using (SqlConnection conn = new SqlConnection(connectionString)) 
    using (SqlCommand cmd = new SqlCommand(select, conn)) 
    { 
     cmd.Parameters.AddWithValue("sessionID", sessionID); 
     cmd.Parameters.AddWithValue("measurementTime", receivedTime); 
     cmd.Parameters.AddWithValue("accelerationX", accelerationX); 
     cmd.Parameters.AddWithValue("accelerationY", accelerationY); 
     cmd.Parameters.AddWithValue("accelerationZ", accelerationZ); 

     try 
     { 
      conn.Open(); 
      cmd.ExecuteNonQuery(); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      return false; 
     } 
    } 
} 

您不再需要在finally块中的通话Close()。当变量conn超出范围时,using块将隐含地调用Dispose()。这将在内部调用Close()方法。

0

默认情况下,连接池已启用,因此重新打开数据库连接并不像我们想象的那样昂贵。为每个Web服务请求打开和关闭连接是完全正确的。