2013-04-11 70 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"); 
      }