2013-05-16 47 views
0

如何追踪分布式传输错误?有什么方法可以确定所有连接仍然打开吗?我需要找到未正确关闭的交易?追踪分布式传输错误

当我从适配器填充表时,出现偶然的分布式事务错误,并显示以下代码。我怀疑这个错误可能不在这个代码中,但这是错误往往会弹出的地方,只有在第二次尝试时,第一个总是可以正常工作。

using (OracleConnection oraConnection = new OracleConnection(connectionString)){ 
using (OracleCommand oraCommand = new OracleCommand("DB_SCHEMA." + rmd.storedprocName, oraConnection)){ 
    oraCommand.CommandType = CommandType.StoredProcedure; 

    if (rmd.parameters != null){ 
     for (int i = 0; i <= rmd.parameters.GetUpperBound(0); i++) 
     { 
      OracleParameter oraParameter = new OracleParameter(); 
      oraParameter.ParameterName = rmd.parameterNames[ i ]; 
      oraParameter.OracleDbType = rmd.parameterTypes[ i ]; 
      oraParameter.Size = 15; 

      string dataType = oraParameter.OracleDbType.ToString().ToUpper(); 

      switch (dataType) 
      { 
       case "VARCHAR2": 
        oraParameter.Value = rmd.parameters[ i ].ToString(); 
        break; 
       case "CHAR": 
        oraParameter.Value = rmd.parameters[ i ].ToString(); 
        break; 
       case "NUMBER": 
        oraParameter.Value = Convert.ToDouble(rmd.parameters[ i ]); 
        break; 
       case "DATE": 
        oraParameter.Value = Convert.ToDateTime(rmd.parameters[ i ]); 
        break; 
       default: 
        oraParameter.Value = rmd.parameters[ i ].ToString(); 
        break; 
      } 

      oraCommand.Parameters.Add(oraParameter); 

     } 
    } 

    oraCommand.Parameters.Add("RS", Oracle.DataAccess.Client.OracleDbType.RefCursor).Direction = ParameterDirection.Output; 
    OracleDataAdapter oraDataAdapter = new OracleDataAdapter(oraCommand); 
    oraDataAdapter.Fill(dataTable); //< -- error is thrown here 
} 
} 

回答

0

我不知道究竟哪里出了问题是源自,但我猜想这是由于使用的OracleDataAdapter而你已经有一个和OracleCommand对象OracleConnection

我认为使用OracleDataReader填写表格并调用Open()Close()方法把你的连接将更加清洁。

后您将所有的参数oraCommand试试这个,而不是你DataAdapter

oraConnection.Open(); 
    OracleDataReader dr = oraCommand.ExecuteReader(); 
    dataTable.Load(dr); 
    oraConnection.Close(); 

同样,我不认为这会一定“修复”您的交易错误,但它只能保证你在执行存储过程时有一个打开的连接,从而使连接更易于管理。

下面是一个使用TransactionScope对象为数据访问的例子:

try 
    { 
     using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions(){IsolationLevel = IsolationLevel.ReadCommitted})) 
     try 
     { 
      CallYourDataAccessMethodsHere(); 
      scope.Complete(); 
     } 
     catch (Exception ex) 
     { 
      //Handle or log the error during the transaction 
     } 
    } 
    catch (Exception ex) 
    { 
     //This will catch a TransactionAbortedException and hopefully help track down the problem 
    } 
在MSDN
+0

,它说:“不止一个OracleDataReader可以在任何给定的时间打开。” (http://msdn.microsoft.com/en-us/library/ab4kxd8h.aspx)所以我尝试使用它打开多个连接,但我仍然有错误。 –

+0

再次想到,您可能需要考虑对所有数据访问方法使用“TransactionScope”,以确保所有访问和读取都在数据库所有事务的范围内完成。另一种可能性是存储过程本身出了问题,也许尝试在那里做一些错误处理而不是回滚?或者发布存储过程,我们可以看看。 –

+0

我在原来的答案中添加了一些代码来演示如何使用'TransactionScope'对象。 –