这IfxTransaction已完成;它不再可用 [英] This IfxTransaction has completed; it is no longer usable

查看:542
本文介绍了这IfxTransaction已完成;它不再可用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问:

当我用的是交易,我会得到下面的错误在约1每100个的纪录。


  

这IfxTransaction已完成;它
  不再可用


当错误发生,或者这是什么错误的原因,我不能指望。

我尝试插入约 607 在同一交易记录。

我的code:

 公共静态INT InsertGroups(列表<组>组)
        {
            DBConnectionForInformix CON =新DBConnectionForInformix();
            con.Open_Connection();
            con.Begin_Transaction();            INT affectedRow = -1;
            字典<字符串,字符串> groupsParameter =新词典<字符串,字符串>();
            尝试
            {
                的foreach(在组A组)
                {
                    groupsParameter.Add(ID,a.GroupId.ToString());
                    groupsParameter.Add(名,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(DEP code,a.Dep code.ToString());
                    groupsParameter.Add(学习code,a.Study code.ToString());
                    groupsParameter.Add(batchnum,a.BatchNum.ToString());
                    affectedRow = DBUtilities.InsertEntityWithTrans(组,groupsParameter,CON);
                    groupsParameter.Clear();
                    如果(affectedRow℃,)
                    {
                        打破;
                    }
                }                如果(affectedRow大于0)
                {
                    con.current_trans.Commit();
                }
            }
            赶上(例外EE)
            {
                字符串消息= ee.Message;
            }            con.Close_Connection();
            返回affectedRow;        }


 公共无效Begin_Transaction()
        {
            如果(this.connection.State == ConnectionState.Open)
            {
                this.current_trans = this.connection.BeginTransaction(IsolationLevel.Serializable);
            }
        }


 公共静态INT InsertEntityWithTrans(字符串tblName,字典<字符串,字符串> dtParams,DBConnectionForInformix current_conn)
        {
            INT结果= -1;
            字符串[] = FIELD_NAMES新的字符串[dtParams.Count]
            dtParams.Keys.CopyTo(FIELD_NAMES,0);
            字符串[] = field_values​​新的字符串[dtParams.Count]
            字符串[] = field_values​​Param新的字符串[dtParams.Count]
            dtParams.Values​​.CopyTo(field_values​​,0);
            的for(int i = 0; I< field_names.Length;我++)
            {
                field_values​​Param [I] =?;
            }
            //----------------------------------------------------------------------------------------------------------------------------------------------
            串insertCmd = @INSERT INTO+ tblName +(+的string.join(,,FIELD_NAMES)+)的值(+的string.join(,,field_values​​Param)+);
            //----------------------------------------------------------------------------------------------------------------------------------------------            IfxCommand COM =新IfxCommand(insertCmd);
            对于(INT J = 0; J< field_names.Length; J ++)
            {
                com.Parameters.Add(,field_values​​ [J]。?);
            }
            尝试
            {                结果= current_conn.Execute_NonQueryWithTransaction(COM);
                如果(current_conn.connectionState == ConnectionState.Open&放大器;&安培;结果大于0)// OK:记录
                {
                    #区域//登录区                    #endregion
                }
            }
            赶上(异常前)
            {                扔;
            }            返回结果;
        }


 公众诠释Execute_NonQueryWithTransaction(IfxCommand COM)
        {
            字符串return_msg =;
            INT RETURN_VAL = -1;
            OPEN_CONNECTION();
            com.Connection = this.connection;
            com.Transaction = current_trans;
            尝试
            {
                RETURN_VAL = com.ExecuteNonQuery();            }
            赶上(IfxException ifxEx)//处理IBM.data.informix:多逮住
            {
                RETURN_VAL = ifxEx.Errors [0] .NativeError;
                return_msg = return_val.ToString();
            }
            赶上(异常前)//处理所有其他异常。
            {
                return_msg = ex.Message;
            }
            最后
            {
                如果(!string.IsNullOrEmpty(return_msg))// catch错误
                {
                    //回滚
                    current_trans.Rollback();
                    Close_Connection();
                    connectionstate = ConnectionState.Closed;
                }            }
            返回RETURN_VAL;
        }


解决方案

您似乎是处理错误,并在两地回滚事务(在 Execute_NonQueryWithTransaction InsertGroups

和从 Execute_NonQueryWithTransaction 返回既用来返回错误codeS和返回受影响的行。但在 InsertGroups 这纯粹是检验一个行受到影响。

你可以有从 Execute_NonQueryWithTransaction 错误code(这样的事务回滚)被视为成功(行插入)在 InsertGroups 并提交失败,则?

总的来说,code需求显著清理:


  1. catch块只投是没有意义的,只是增加了噪音。

  2. 只需使用异常错误处理,一切正常的回报应该表示成功。

Q:

When I use the transactions ,I'll get the following error on about 1 out of every 100 record.

This IfxTransaction has completed; it is no longer usable

I can't expect when the error happen or what is the reason of this error.

I try to insert about 607 record in the same transaction.

My 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;
        }

解决方案

You seem to be handling errors and rolling back the transaction in two places (in Execute_NonQueryWithTransaction and in InsertGroups.

And the return from Execute_NonQueryWithTransaction is used both to return error codes and to return rows affected. But in InsertGroups it is checked purely as a rows affected.

Could you have an error code from Execute_NonQueryWithTransaction (so transaction rolled back) being treated as success (rows inserted) in InsertGroups and the commit then fails?

Overall the code needs significant cleanup:

  1. A catch block to only throw is pointless and just adds noise.
  2. Just use exceptions for error handling, all normal returns should indicate success.

这篇关于这IfxTransaction已完成;它不再可用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆