2013-04-11 73 views
1

我在我的C#設備應用程序中有過程。這是它的外觀:SET TRANSACTION錯誤,C#,Oracle

private void stk_crane_start_movement() 
    { 
     conn.Open(); 
     OracleCommand cmd = new OracleCommand(); 
     OracleTransaction trans; 
     trans = conn.BeginTransaction(); 
     cmd.Transaction = trans; 
     cmd.Connection = conn; 
     conn.AutoCommit = false; 
     cmd.CommandTimeout = 0; 
     cmd.CommandText = "dc.stk_crane_start_movement"; 
     cmd.CommandType = CommandType.StoredProcedure; 
     cmd.Parameters.Add("pn_crane_opr_id_no", OracleDbType.Number).Value = empid.ToString(); 
     cmd.Parameters.Add("pn_crane_movement_id_no", OracleDbType.Number).Value = pn_crane_movement_id_no.ToString(); 
     cmd.Parameters.Add(new OracleParameter("pv_error", OracleDbType.VarChar)); 
     cmd.Parameters["pv_error"].Direction = ParameterDirection.Output; 
     string pv_error; 
     cmd.ExecuteNonQuery(); 
     pv_error = cmd.Parameters["pv_error"].Value.ToString(); 
     if (pv_error.ToString() == "") 
     { 
      trans.Commit(); 
      trans.Dispose(); 
      conn.Close(); 
      cmd.Dispose(); 
     } 
     else 
     { 
      trans.Rollback(); 
      MessageBox.Show("" + pv_error, "Error"); 
     } 
    } 

我越來越ORA-01453: SET TRANSACTION must be first statement of transactiontrans = conn.BeginTransaction();

可有人請向我解釋什麼,我做錯了?

我也嘗試過這樣的:

private void stk_crane_start_movement() 
    { 
     conn.Open(); 
     OracleCommand cmd = conn.CreateCommand(); 
     OracleTransaction trans; 
     trans = conn.BeginTransaction(IsolationLevel.ReadCommitted); 
     cmd.Transaction = trans; 
     try 
     { 
      cmd.CommandText = "dc.stk_crane_start_movement"; 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add("pn_crane_opr_id_no", OracleDbType.Number).Value = empid.ToString(); 
      cmd.Parameters.Add("pn_crane_movement_id_no", OracleDbType.Number).Value = pn_crane_movement_id_no.ToString(); 
      cmd.Parameters.Add(new OracleParameter("pv_error", OracleDbType.VarChar)); 
      cmd.Parameters["pv_error"].Direction = ParameterDirection.Output; 
      cmd.ExecuteNonQuery(); 
      trans.Commit(); 
     } 

     catch 
     { 
      pv_error = cmd.Parameters["pv_error"].Value.ToString(); 
      MessageBox.Show("" + pv_error, "Error"); 

      try 
      { 
       trans.Rollback(); 
      } 
      catch (OracleException ex) 
      { 
       MessageBox.Show("Rollback failed" + ex, "Exception Error"); 
      } 
     } 
    } 

但因爲它不是我期待它不通過嘗試catch語句去一個異常錯誤。 我希望它在我的pv_error變量被填充時回滾。這就是爲什麼我在第一個例子中包含if語句的原因。

此外,我不這樣一個前有任何其他交易..

+0

如果你把conn.AutoCommit = false;在開始交易之前? – Sebas 2013-04-11 12:51:37

+0

嘗試切換爲使用[TransactionScope](http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx)。像[this](http://stackoverflow.com/questions/15268430/how-to-implement-transaction/15268649#15268649) – 2013-04-11 12:53:05

+0

不,仍然是同樣的錯誤。 tx tho – 2013-04-12 12:48:19

回答

0

有一個建議here如果你已經有一個打開的事務,你可能會看到這個錯誤。他們建議承諾或回滾任何開放的東西。與SQL Server不同,我已經能夠在Oracle中發佈預防性的「COMMIT」語句,而不必知道我是否有任何開放的東西。

我你的代碼和sample code here之間看到的唯一區別是,他們扳平命令對象連接到其指定交易之前:

OracleCommand command = connection.CreateCommand(); 
command.Transaction = transaction; 

你可能想嘗試的變異。你沒有設置隔離級別,所以oracle oci.dll below version 10.2的問題可能不適用於此。

+0

我也見過你的例子。我編輯了我的問題。在那裏你會看到我已經嘗試過,就像你給的例子。我也解釋了爲什麼它不適合我。 – 2013-04-12 12:49:37

+0

對不起@Werner,我不確定接下來要嘗試什麼。你有沒有嘗試把「cmd.Transaction = trans」在BeginTransaction之前?另外,爲什麼不繼續忽略隔離級別?你知道你的oci.dll的版本號嗎? ...如果你確實找到了解決方案,如果你可以發佈給大家的信息,那將是非常好的。 – criticalfix 2013-04-15 12:41:35

0

根據MSDN docs,您的第二個版本正確使用該事務。所以如果你把它和你的if語句結合起來,你應該沒問題:

private void stk_crane_start_movement() 
    { 
     conn.Open(); 
     OracleCommand cmd = conn.CreateCommand(); 
     OracleTransaction trans; 
     trans = conn.BeginTransaction(IsolationLevel.ReadCommitted); 
     cmd.Transaction = trans; 
     try 
     { 
      cmd.CommandText = "dc.stk_crane_start_movement"; 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add("pn_crane_opr_id_no", OracleDbType.Number).Value = empid.ToString(); 
      cmd.Parameters.Add("pn_crane_movement_id_no", OracleDbType.Number).Value = pn_crane_movement_id_no.ToString(); 
      cmd.Parameters.Add(new OracleParameter("pv_error", OracleDbType.VarChar)); 
      cmd.Parameters["pv_error"].Direction = ParameterDirection.Output; 
      cmd.ExecuteNonQuery(); 
      pv_error = cmd.Parameters["pv_error"].Value.ToString();     
      if (pv_error.ToString() == "") 
      { 
       trans.Commit(); 
       trans.Dispose(); 
       conn.Close(); 
       cmd.Dispose(); 
      } 
      else 
      { 
       trans.Rollback(); 
       MessageBox.Show("" + pv_error, "Error"); 
      }