2011-06-26 5 views
1

Q:Cette IfxTransaction est terminée; il n'est plus utilisable

Lorsque j'utilise les transactions, j'obtiens l'erreur suivante sur environ 1 enregistrement sur 100.

Cette opération IfxTransaction est terminée; il n'est plus utilisable

Je ne peux pas attendre lorsque l'erreur se produit ou quelle est la raison de cette erreur.

J'essaie d'insérer environ 607 enregistrement dans la même transaction.

Mon code:

public static int InsertGroups(List<Group> groups) 
     { 
      DBConnectionForInformix con = new DBConnectionForInformix(""); 
      con.Open_Connection(); 
      con.Begin_Transaction(); 

      int affectedRow = -1; 
      Dictionary<string, string> groupsParameter = new Dictionary<string, string>(); 
      try 
      { 
       foreach (Group a in groups) 
       { 
        groupsParameter.Add("id", a.GroupId.ToString()); 
        groupsParameter.Add("name", a.Name); 
        groupsParameter.Add("studentcount", a.StudentCount.ToString()); 
        groupsParameter.Add("divisiontag", a.DivisionTag.ToString()); 
        groupsParameter.Add("entireclass", a.EntireClass.ToString()); 
        groupsParameter.Add("classid", a.ClassId.ToString()); 
        groupsParameter.Add("depcode", a.DepCode.ToString()); 
        groupsParameter.Add("studycode", a.StudyCode.ToString()); 
        groupsParameter.Add("batchnum", a.BatchNum.ToString()); 
        affectedRow = DBUtilities.InsertEntityWithTrans("groups", groupsParameter, con); 
        groupsParameter.Clear(); 
        if (affectedRow < 0) 
        { 
         break; 
        } 
       } 

       if (affectedRow > 0) 
       { 
        con.current_trans.Commit(); 
       } 
      } 
      catch (Exception ee) 
      { 
       string message = ee.Message; 
      } 

      con.Close_Connection(); 
      return affectedRow; 

     } 

public void Begin_Transaction() 
     { 
      if (this.connection.State == ConnectionState.Open) 
      { 
       this.current_trans = this.connection.BeginTransaction(IsolationLevel.Serializable); 
      } 
     } 

public static int InsertEntityWithTrans(string tblName, Dictionary<string, string> dtParams, DBConnectionForInformix current_conn) 
     { 
      int Result = -1; 
      string[] field_names = new string[dtParams.Count]; 
      dtParams.Keys.CopyTo(field_names, 0); 
      string[] field_values = new string[dtParams.Count]; 
      string[] field_valuesParam = new string[dtParams.Count]; 
      dtParams.Values.CopyTo(field_values, 0); 
      for (int i = 0; i < field_names.Length; i++) 
      { 
       field_valuesParam[i] = "?"; 
      } 
      //---------------------------------------------------------------------------------------------------------------------------------------------- 
      string insertCmd = @"INSERT INTO " + tblName + " (" + string.Join(",", field_names) + ") values (" + string.Join(",", field_valuesParam) + ")"; 
      //---------------------------------------------------------------------------------------------------------------------------------------------- 

      IfxCommand com = new IfxCommand(insertCmd); 
      for (int j = 0; j < field_names.Length; j++) 
      { 
       com.Parameters.Add("?", field_values[j]); 
      } 
      try 
      { 

       Result = current_conn.Execute_NonQueryWithTransaction(com); 
       if (current_conn.connectionState == ConnectionState.Open && Result > 0)//OK: logging 
       { 
        # region // Log Area 

        #endregion 
       } 
      } 
      catch (Exception ex) 
      { 

       throw; 
      } 

      return Result; 
     } 

public int Execute_NonQueryWithTransaction(IfxCommand com) 
     { 
      string return_msg = ""; 
      int return_val = -1; 
      Open_Connection(); 
      com.Connection = this.connection; 
      com.Transaction = current_trans; 
      try 
      { 
       return_val = com.ExecuteNonQuery(); 

      } 
      catch (IfxException ifxEx)// Handle IBM.data.informix : mostly catched 
      { 
       return_val = ifxEx.Errors[0].NativeError; 
       return_msg = return_val.ToString(); 
      } 
      catch (Exception ex)// Handle all other exceptions. 
      { 
       return_msg = ex.Message; 
      } 
      finally 
      { 
       if (!string.IsNullOrEmpty(return_msg))//catch error 
       { 
        //rollback 
        current_trans.Rollback(); 
        Close_Connection(); 
        connectionstate = ConnectionState.Closed; 
       } 

      } 
      return return_val; 
     } 

Répondre

3

Vous semblez erreurs de manipulation et annulation de la transaction en deux endroits (en Execute_NonQueryWithTransaction et au InsertGroups.

Et le retour de Execute_NonQueryWithTransaction est utilisé à la fois pour retourner les codes d'erreur et de renvoyer les lignes affectées. Mais dans InsertGroups il est vérifié purement comme des lignes affectées.

Pourriez-vous avoir un code d'erreur de Execute_NonQueryWithTransaction (afin que la transaction annulée) soit considéré comme un succès (lignes insérées) dans InsertGroups et le commit échoue alors?

le code général a besoin d'un nettoyage important:

  1. Un bloc catch à seulement un jet est inutile et ajoute que du bruit.
  2. Il suffit d'utiliser des exceptions pour la gestion des erreurs, tous les retours normaux devraient indiquer le succès.
+0

'catch (Exception ex) // Handle toutes les autres exceptions. { return_msg = ex.Message; Je reçois l'erreur ici 'This IfxTransaction a terminé; Il n'est plus utilisable –

+0

Pourriez-vous re-factoriser mon code s'il vous plaît à ce que vous avez dit? Et si je le refactorise .Ce problème sera résolu? Parce que quand j'utilise le normal'Insert 'sans transaction tout va bien. –

+1

@just_name: Je n'ai pas Informaix ici, donc je devinerais trop sur le code. Pas difficile de se débarrasser de l'essayer/attrape tous sauf 'InsertGroups 'qui ferait la plupart de ce que je suggère. – Richard

Questions connexes