此 IfxTransaction 已完成;它不再可用

Posted

技术标签:

【中文标题】此 IfxTransaction 已完成;它不再可用【英文标题】:This IfxTransaction has completed; it is no longer usable 【发布时间】:2011-06-26 10:20:51 【问题描述】:

问:

当我使用交易时,每 100 条记录中约有 1 条会出现以下错误。

此 IfxTransaction 已完成;它 不再可用

我无法预料错误何时发生或此错误的原因是什么。

我尝试在同一事务中插入大约607 记录。

我的代码:

 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;
        

【问题讨论】:

【参考方案1】:

您似乎在两个地方处理错误并回滚事务(Execute_NonQueryWithTransactionInsertGroups

Execute_NonQueryWithTransaction 的返回既用于返回错误代码,也用于返回受影响的行。但在InsertGroups 中,它纯粹是作为受影响的行进行检查的。

您能否将来自Execute_NonQueryWithTransaction 的错误代码(因此事务回滚)在InsertGroups 中视为成功(插入的行)然后提交失败?

总体而言,代码需要大量清理:

    只扔掉的 catch 块是没有意义的,只会增加噪音。 只要使用异常处理错误,所有正常返回都应该表​​示成功。

【讨论】:

` catch (Exception ex)// 处理所有其他异常。 return_msg = ex.Message; ` 我在这里得到错误This IfxTransaction has completed; it is no longer usable 您能否按照您所说的重新重构我的代码?如果我重构它。这将解决我的问题?因为当我使用正常的“插入”而不进行事务时,一切都会好起来。 @just_name:我这里没有 Informaix,所以会猜测太多代码。除了 InsertGroups 之外,不难去除所有的 try/catch,这将完成我所建议的大部分工作。 hmmmm,你的意思是,我应该从InsertGroups 中删除Try &amp; catch @just_name:请阅读我的最后一条评论:建议您删除最外层函数(即InsertGroups)中的try/catch except

以上是关于此 IfxTransaction 已完成;它不再可用的主要内容,如果未能解决你的问题,请参考以下文章

如何懒洋洋地生成一个完成的项目序列并迭代它

此博客已不更新,作者的个人域名LIZHONGC.COM已经启用。

颤振错误:此小部件已卸载,因此状态不再具有上下文(应视为已失效)

为啥在microsoft visual c++2010 中输入的所有程序都显示此项目已过期

评论alpha发布

如何在HTML / Javascript中创建可编辑的组合框?