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的物件查詢,不會報錯。