2013-04-23 75 views
0

我有一個使用實體框架和MySQL數據庫的ASP.NET Web應用程序。我正在做一些動態表的工作,所以採取了寫入原始SQL。有什麼我需要添加,以使此代碼線程安全?此代碼可以並且將被我的系統的每個用戶非常頻繁地調用。它總是打電話給INFORMATION_SCHEMA那個錯誤。零星「目前不支持多個同時連接」

這是我收到相當經常試圖調用AddMessageAction(但不是每次)錯誤:

UserActionModel:CheckTableExists ex: The underlying provider failed on Open.. 
4/23/2013 9:00:24 AM: UserActionModel:CheckTableExists inner ex: System.NotSupportedException: Multiple simultaneous connections or connections with different connection strings inside the same transaction are not currently supported. 
    at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception) 
    at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex) 
    at MySql.Data.MySqlClient.MySqlConnection.Open() 
    at System.Data.EntityClient.EntityConnection.OpenStoreConnectionIf(Boolean openCondition, DbConnection storeConnectionToOpen, DbConnection originalConnection, String exceptionCode, String attemptedOperation, Boolean& closeStoreConnectionOnFailure). 

,代碼:

public static class UserActionModel 
{ 

private const string databaseName = "chat"; 

public static string CheckTableExists(long _userId) 
{ 
    string tableName = null; 
    List<long> tableExists; 

    try 
    { 
     string date = DateTime.Now.ToUniversalTime().Year.ToString() + DateTime.Now.ToUniversalTime().Month.ToString("D2") + DateTime.Now.ToUniversalTime().Day.ToString("D2"); 

     tableName = "user_actions_" + date + "_" + _userId; 

     string sql = "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_NAME = '" + tableName + "' AND TABLE_SCHEMA = 'archive'"; 

     using (var readContext = new ArchiveConnector()) 
     { 
      tableExists = readContext.Database.SqlQuery<long>(sql).ToList(); 
      readContext.Database.Connection.Close(); 
     } 

     if (tableExists.Any(tableExist => tableExist == 0)) 
     { 
      sql = "CREATE TABLE IF NOT EXISTS `" + tableName + "` (" 
        + "`id` bigint(20) NOT NULL AUTO_INCREMENT, " 
        + "`user_id` bigint(20) NOT NULL, " 
        + "`user_device_id` bigint(20) NOT NULL, " 
        + "`coordinate_address_id` bigint(20) NOT NULL, " 
        + "`message_id` bigint(20) DEFAULT NULL, " 
        + "`created` datetime NOT NULL, " 
        + "PRIMARY KEY (`id`), " 
        + "KEY `user_id` (`user_id`), " 
        + "KEY `user_device_id` (`user_device_id`), " 
        + "KEY `coordinate_address_id` (`coordinate_address_id`), " 
        + "KEY `message_id` (`message_id`); " 

      using (var writeContext = new ArchiveConnector()) 
      { 
       writeContext.Database.ExecuteSqlCommand(sql); 
       writeContext.SaveChanges(); 
       writeContext.Database.Connection.Close(); 

      } 
     } 
    } 
    catch (Exception ex) 
    { 
     Logger.LogMessage("UserActionModel:CheckTableExists ex: " + ex.Message); 

     if (ex.InnerException != null) 
      Logger.LogMessage("UserActionModel:CheckTableExists inner ex: " + ex.InnerException); 

     tableName = null; 
    } 

    return tableName; 
} 

public static void AddMessageAction(long _messageId, long _userId, long _userDeviceId, long _coordinateAddressId) 
{ 
    try 
    { 
     string tableName = CheckTableExists(_userId); 

     if (String.IsNullOrEmpty(tableName)) return; 

     using (var dataContext = new ArchiveConnector()) 
     { 
      string sql = "INSERT INTO " + tableName + " " 
       + "(user_id, user_device_id, coordinate_address_id, message_id, created) " 
       + "VALUES " 
       + "(" + _userId + ", " + _userDeviceId + ", " + _coordinateAddressId + ", " + _messageId + ", NOW());"; 

      dataContext.Database.ExecuteSqlCommand(sql); 
      dataContext.SaveChanges(); 
     } 
    } 
    catch (Exception ex) 
    { 
     Logger.LogMessage("UserActionModel:AddMessageAction (" + _messageId + ") ex: " + ex.Message); 
    } 
} 
}  

從我的web.config連接字符串中刪除persist security info=True做沒有區別(我讀到這是一個可能的解決方案)。

UDPATE:從連接器6.6.4更新到6.6.5。不用找了。 UDPATE:從連接器6.6.5更新爲6.7.1 Alpha。不用找了。

回答

0

ArchiveConnectorDispose方法未關閉其MySQL連接。當你:

using (var writeContext = new ArchiveConnector()) 

上的連接:

using (var readContext = new ArchiveConnector()) 

仍然是開放的,和MySQL不支持在同一事務的多個連接。確保您的連接在ArchiveConnector.Dispose()上關閉。

祝你好運。

+0

我以爲'using'塊的結束會自動處理所有的Dispose調用?從MSDN:'你在using語句中創建一個實例,以確保當using語句退出時,在對象上調用Dispose。 – Julien 2013-04-23 15:07:25

0

我在不同的連接器上從using內撥打AddMessageAction()。不要這樣做。

相關問題