2017-04-13 139 views
0

我有一个C#Lambda函数,它在第一次执行时起作用,但在第二次执行时失败。 我创建了一些日志来帮助我排查问题出在哪里,但我正在努力弄清楚实际发生的事情。AWS Lambda函数在第一次运行时工作,但不是第二次

首先执行日志:

START RequestId: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX Version: $LATEST 

1. Connecion to Database is Open 
2. Running Query: SELECT * FROM Employee3 
3. Returning Results 
4. Close connection 
5. Close reader 
6. Dispose cmd 
7. Configure encoding and string to stream 
END RequestId: XXXXXXXXXXXXXXXXXXXXXXXX 
REPORT RequestId: XXXXXXXXXXXXXXXXXXXXXXXX Duration: 10097.73 ms Billed Duration: 10100 ms Memory Size: 128 MB Max Memory Used: 41 MB 

响应:(我知道这是不是有效的JSON,这我最终的目标,但是这将是下一个项目我解决,一旦我算出这个

Connecion to Database is Open 
Joe 
Bob 
Mary 

第二次执行日志:

START RequestId: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX Version: $LATEST 

    1. Connecion to Database is Open 
    2. Running Query: SELECT * FROM Employee3 
     Connection must be valid and open.: InvalidOperationException 
     at MySql.Data.MySqlClient.MySqlCommand.Throw(Exception ex) 
     at MySql.Data.MySqlClient.MySqlCommand.CheckState() 
     at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior) 
     at LambdaDBTest.Function.returnRows(MySqlConnection connection) 
     at LambdaDBTest.Function.FunctionHandler(Stream input, ILambdaContext context) 
     at lambda_method(Closure , Stream , Stream , ContextInfo) 


    END RequestId: XXXXXXXXXXXXXXXXXXXXXXXX 
    REPORT RequestId: XXXXXXXXXXXXXXXXXXXXXXXX Duration: 1203.12 ms Billed Duration: 1300 ms Memory Size: 128 MB Max Memory Used: 47 MB 

下面是我使用的代码:

using System; 
using System.IO; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using MySql.Data.MySqlClient; 
using Amazon.Lambda.Core; 
using Amazon.Lambda.Serialization; 
using System.Text; 

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 
[assembly: LambdaSerializerAttribute(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))] 

namespace LambdaDBTest 
{ 
    public class Function 
    { 
     /// <summary> 
     /// A simple function that takes a string and does a ToUpper 
     /// </summary> 
     /// <param name="input"></param> 
     /// <param name="context"></param> 
     /// <returns></returns> 

     public Stream FunctionHandler(Stream input, ILambdaContext context) 
     { 
      var dbCon = DBConnection.Instance(); 

      dbCon.Server = "AWS-URI"; 
      dbCon.DatabaseName = "DBNAME"; 
      dbCon.User = "DBUSER"; 
      dbCon.Password = "DBPASS"; 
      string textInput; 
      if (dbCon.IsConnect()) 
      { 
       textInput = "Connecion to Database is Open"; 
       LambdaLogger.Log("\n 1. " + textInput); 
       textInput += returnRows(dbCon.Connection); 
      } 
      else 
      { 
       textInput = "\n Connecion to Database is NOT Open"; 
      } 
      dbCon.Close(); 
      LambdaLogger.Log("\n 7. Configure encoding and string to stream\n"); 
      input = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(textInput)); 
      return input; 
     } 

     public static MemoryStream GenerateStreamFromString(string value) 
     { 
      return new MemoryStream(Encoding.UTF8.GetBytes(value ?? "")); 
     } 

     static string returnRows(MySqlConnection connection) 
     { 
      string output = null; 
      string query = @"SELECT * FROM Employee3"; 
      LambdaLogger.Log("\n 2. Running Query: " + query); 
      var cmd = new MySqlCommand(query, connection); 
      var reader = cmd.ExecuteReader(); 
      LambdaLogger.Log("\n 3. Returning Results"); 
      while (reader.Read()) 
      { 
       output += "\n" + (string)reader["Name"]; 
      } 
       LambdaLogger.Log("\n 4. Close connection"); 
      connection.Close(); 


       LambdaLogger.Log("\n 5. Close reader"); 
      reader.Close(); 

       LambdaLogger.Log("\n 6. Dispose cmd"); 
      cmd.Dispose(); 
      return output + "\r"; 
     } 
    } 
} 

因此,代码是非常基本的,并使用MySql.Data 6.10.1-β的Nu-获取软件包MySQL和有点剪切和粘贴工作AWS Lambda。

我不明白为什么我在第一次尝试而不是第二次执行时遇到问题。根据我的理解,Lambda的状态保存为零。

希望我做了一些愚蠢或缺少明显的东西,我很乐意收到通知。如果您需要更多信息,请告诉我。

编辑的代码:

所以修复被发现,如下图所示:

public Stream FunctionHandler(Stream input, ILambdaContext context) 
     { 
      var dbCon = DBConnection.Instance(); 

      dbCon.Server = "######.rds.amazonaws.com"; 
      dbCon.DatabaseName = "#####"; 
      dbCon.User = "#####"; 
      dbCon.Password = "######"; 
      string textInput; 
      if (dbCon.IsConnect()) 
      { 
       textInput = "Connecion to Database is Open"; 
       LambdaLogger.Log("\n 1. " + textInput); 
       textInput += returnRows(dbCon.Connection); 
      } 
      else 
      { 
       textInput = "\n Connecion to Database is NOT Open"; 
      } 

      // LambdaLogger.Log("\n 7. Close Database connection"); 
      //dbCon.Close(); 
      LambdaLogger.Log("\n 8. Configure encoding and string to stream\n"); 
      input = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(textInput)); 
      return input; 
     } 

     public static MemoryStream GenerateStreamFromString(string value) 
     { 
      return new MemoryStream(Encoding.UTF8.GetBytes(value ?? "")); 
     } 

     static string returnRows(MySqlConnection connection) 
     { 
      string output = null; 
      string query = @"SELECT * FROM Employee3"; 
      LambdaLogger.Log("\n 2. Running Query: " + query); 
      var cmd = new MySqlCommand(query, connection); 
      var reader = cmd.ExecuteReader(); 
      LambdaLogger.Log("\n 3. Returning Results"); 
      while (reader.Read()) 
      { 
       output += "\n" + (string)reader["Name"]; 
      } 

      // LambdaLogger.Log("\n 4. Close connection"); 
      //connection.Close(); 


       LambdaLogger.Log("\n 5. Close reader"); 
      reader.Close(); 

      // LambdaLogger.Log("\n 6. Dispose cmd"); 
      //cmd.Dispose(); 
      return output + "\r"; 
     } 

过程reader被LAMBDA冻结,所以虽然我没有必要需要关闭MySQL连接因连接到.net MySQL驱动程序的连接池,我确实需要调用reader.Close();来终止冻结的进程。谢谢你Udo举行:)

+1

现在可能要更改您的用户名和密码 – BurnsBA

回答

1

我有一个怀疑。 代码看起来像你每次打开和关闭连接都很好。但是,您的驱动程序可能不会真正关闭连接,而只是将其返回到池中。 AWS freezes请求之间的实例。因此,如果与数据库的连接由池保持打开状态,则实际上可能会由于您的代码被AWS冻结而断开连接。

望着.net MySQL driver documentation它指出:“The Connector/Net supports connection pooling for better performance and scalability with database-intensive applications. This is enabled by default.

您没有提供一个连接字符串,但你也许应该尝试禁用连接池添加类似Pooling=false。有other options您可能也想尝试。

+0

您可能会在此处找到正确的路线。该数据库托管在RDS实例中,因此我认为我不能访问该数据库。我只是更新我的代码,删除所有连接关闭语句,然后收到以下错误'“errorMessage”:“已经有一个打开的DataReader与此连接关联,必须先关闭。”......这绝对是一个线索: ) – Majickal

相关问题