1. 程式人生 > >Oraclee 事務處理以及在c#中使用oracle的事務處理

Oraclee 事務處理以及在c#中使用oracle的事務處理

1、 savepoint(建立儲存點,用於失誤時回滾到儲存點)

建立儲存點a1:savepoint a1;

............................[其間幹了很多事]

再建立儲存點a2:savepoint a2;

............................[又再幹了很多事]

回滾到a2儲存點:rollback to a2;

回滾到a1儲存點:rollback to a1;

如果不指定儲存點即為取消全部事務,如:rollback;

注意:如果建立儲存點後執行過:commit語句,則為提出交事務,確認事務變化、結束事務、刪除所有儲存點、釋放鎖。

當使用commit語句結束事務後,其它會話將可以檢視到事務變化後的新資料。

2、只讀事務:transaction read only

一旦設定了只讀事務(一般資料庫管理員設定) ,則其它人提交上來的動作都不會看到。

如管理員操作:set transaction read only;

A使用者操作增刪改:。。。。。。(自已進行查詢時可以看到所影響的資料)

B使用者查詢時:。。。。。。。。(看不到A使用者進行過操作所影響的資料)

修改事務為讀寫的命令為:SET TRANSACTION READ WRITE;

3、在C#程式碼中使用Oracle的資料庫事務

OracleTransaction類的概述
     應用程式通過針對OracleConnection物件呼叫 BeginTransaction 來建立OracleTransaction物件。對OracleTransaction物件執行與該事務關聯的所有後續操作(例如提交或中止該事務)。

OracleTransaction的成員主要有:
屬性:
Connection,指定與該事務關聯的OracleConnection物件;
IsolationLevel,指定該事務的IsolationLevel;列舉型別,用於對事物的鎖定,取值有Chaos、ReadCommited、ReadUncommited、RepeatableRead、Serializable、Unspecified。
方法:
Commit,提交SQL資料庫事務;
Rollback , 從掛起狀態回滾事務;

第一個示例:
public void 函式名稱()
{
string strUpdateSql1 = "update 表名 set XH='...' where XH='...' and LCGZ_ID='...';
string strUpdateSql2 = "update 表名 set XH='...' where BZGZ_ID='...';
OracleConnection conn = new OracleConnection();
conn.ConnectionString = "資料庫連線字串";
conn.Open();
OracleTransaction updateProcess = conn.BeginTransaction();

try
{
   OracleCommand comm1 = conn.CreateCommand();
   comm1.CommandText = strUpdateSql1;
   comm1.Transaction = updateProcess;
   comm1.ExecuteNonQuery();

   OracleCommand comm2 = conn.CreateCommand();
   comm2.CommandText = strUpdateSql2;
   comm2.Transaction = updateProcess;
   comm2.ExecuteNonQuery();

   updateProcess.Commit();
}
catch()
{
   updateProcess.Rollback();
}
finally
{
   conn.Close();
}
}


第二個示例:
public static bool 函式名2(int fID)
{
OracleConnection conn = new OracleConnection();
conn.ConnectionString = "資料庫連線字串";
conn.Open();
OracleTransaction deleteProcess = conn.BeginTransaction();            

try
{
   ArrayList alObjects = GetObjects();
   foreach(object o in alObjects)
   {
    OracleCommand tmpComm = conn.CreateCommand();
    tmpComm.Transaction = deleteProcess;
    tmpComm.CommandText = "delete from 表1名 where BZGZ_ID="+o.ID;
    tmpComm.ExecuteNonQuery();

    OracleCommand tmpComm2 = conn.CreateCommand();
    tmpComm2.Transaction = deleteProcess;
    tmpComm2.CommandText = "delete from 表2名 where BZGZ_ID="+o.ID;
    tmpComm2.ExecuteNonQuery();
   }
   OracleCommand comm = conn.CreateCommand();
   comm.Transaction = deleteProcess;
   comm.CommandText = "delete from 表3名 where LCGZ_ID="+fID;
   comm.ExecuteNonQuery();

   deleteProcess.Commit();
   return true;
}
catch()
{
   deleteProcess.Rollback();
   return false;
}
finally
{
   conn.Close();
}

 =========================================================================

Connection一旦開了一個事務,則執行的命令就必須和事務相關
要注意的是,在事務進行中,不能再對同一個資料庫連線(OracleConnection)再進行事務外的資料的查詢和讀取
,

也就是說,類似下邊的語句是不能執行的:
OracleDataAdapter mAdp = new OracleDataAdapter(sSql, mCon);
DataTable mDst = new DataTable();
mAdp.Fill(mDst);

而是得加一條語句,在事務內進行查詢:
OracleDataAdapter mAdp = new OracleDataAdapter(sSql, mCon);
if (trans != null) mAdp.SelectCommand.Transaction = trans;
DataTable mDst = new DataTable();
mAdp.Fill(mDst);

總結:在事務塊內,如果使用同樣的Connection物件查詢,但不指定事務,會報錯,
           在事務提交後,或者不使用相同的Connection的物件查詢,不會報錯。