數據庫事務(簡稱: 事務)是數據庫管理系統執行過程中的一個邏輯單位,由一個有限的數據庫操作序列構成。當事務被提交給了DBMS(數據庫管理系統),則DBMS(數據庫管理系統)需要確保該事務中的所有操作都成功完成且其結果被永久保存在數據庫中,如果事務中有的操作沒有成功完成,則事務中的所有操作都需要被回滾,回到事務執行前的狀態;同時,該事務對數據庫或者其他事務的執行無影響,所有的事務都好像在獨立的運行。
事務的特性(ACID性質)
原子性(Atomic)
事務作為一個整體被執行,包含在其中的對數據庫的操作要么全部被執行,要么都不執行。
一致性(Consistency)
事務應確保數據庫的狀態從一個一致狀態轉變為另一個一致狀態。一致狀態的含義是數據庫中的數據應滿足完整性約束。
隔離性(Isolation)
多個事務並發執行時,一個事務的執行不應影響其他事務的執行。
持久性(Durability)
已被提交的事務對數據庫的修改應該永久保存在數據庫中。
下面介紹事務的具體使用。
事務在數據庫中的使用
- BEGIN TRANSACTION
- --向Table1表中插入記錄
- INSERT INTO Table1 VALUES('1','1')
- SET @Err1=@@ERROR
- --向Table2表插入記錄
- INSERT INTO Table2 VALUES('1','1')
- SET @Err2=@@ERROR
- IF(@Err1=0 AND @Err2=0)
- COMMIT TRANSACTION --事務提交
- ELSE
- ROLLBACK TRANSACTION --事務回滾
@@ERROR:完成 Transact-SQL 語句的執行時,如果語句執行成功,則 @@ERROR 設置為 0。若出現一個錯誤,則返回一條錯誤信息。@@ERROR 返回此錯誤信息代碼,直到另一條 Transact-SQL 語句被執行。
事務在.NET代碼中的使用
首先添加引用usingSystem.Transactions;
(1)只在D層使用事務
- //設定事務的級別
- TransactionOptions option = new TransactionOptions();
- option.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
- using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, option))
- {
- //標志是否更改成功
- bool flag = false;
- bool flagUpdate = false;
- //更新Table1中數據
- string sqlUpText = "UPDATE Table1 SET actionReason = '1'";
- flagUpdate = sqlHelper.ExecuteNonQuery(sqlUpText,CommandType.Text);
- //更新Table2中數據
- string sqlText = "UPDATE Table2 SET isAvailable ='否' ";
- flag = sqlHelper.ExecuteNonQuery(sqlText, CommandType.Text);
- if (flag && flagUpdate)
- {
- ts.Complete();
- return true;
- }
- else {
- return false;
- }
- }
(2)事務在B層的使用
B層代碼
- //首先引用 System.Data和System.Data.SqlClient命名空間
- //定義事務執行所使用的鏈接
- SqlConnection sqlCon = new SqlConnection(ConfigurationManager.ConnectionStrings["strConnDB"].ToString());
- //打開連接
- sqlCon.Open();
- //定義事務
- SqlTransaction sqlTran = sqlCon.BeginTransaction(IsolationLevel.ReadCommitted);
- //用try...Catch...finally保證事務在出錯時會回滾
- try
- {
- //向課程表中添加數據
- OptionalCourseScheduleLinkDAL OptionalCourseSchedule = new OptionalCourseScheduleLinkDAL();
- //將新建立的連接和事務一起傳回D層
- IsAddOptionalCourseSchedule = OptionalCourseSchedule.AddOptionalCourseSchedule(enOptionalCourseSchedule,sqlCon,sqlTran);
- //更新授課關系表中的單雙周
- CourseTeachClassLinkDAL CourseTeachClass = new CourseTeachClassLinkDAL();
- //添加D層的方法,調用sqlHelper中執行事務的方法:ExecNoSelect(string cmdText, SqlParameter[] paras, CommandType cmdType, SqlConnection sqlConns, SqlTransaction sqlTran)
- //將新建立的連接和事務一起傳回D層
- IsUpdateCourseTeachClass = CourseTeachClass.UpdateCourseTeachClassOddEven(enCourseTeachClass,sqlCon,sqlTran);
- //若添加和更新有一者返回false,事務回滾
- if (IsAddOptionalCourseSchedule && IsUpdateCourseTeachClass)
- {
- //如果都為真,提交
- sqlTran.Commit();
- sqlCon.Close();
- return true;
- }
- else {
- sqlTran.Rollback();
- }
- }
- catch (Exception)
- {
- //出現異常時,事物回滾
- sqlTran.Rollback();
- }
- finally {
- sqlCon.Close();
- }
- return false;
D層代碼
- public Boolean AddOptionalCourseSchedule(OptionalCourseScheduleLinkEntity enOptionalCourseScheduleLink, SqlConnection sqlCon, SqlTransaction sqlTran)
- {
- //聲明一個布爾型變量
- Boolean blnIsResult = false;
- //執行SQL字符串名
- string strSQL = "insert into TBR_OptionalCourseScheduleLink(TeachClassID,RoomID,WorkDay,ClassBegin,ClassEnd) VALUES(@TeachClassID,@RoomID,@WorkDay,@ClassBegin,@ClassEnd)";
- //字符串數組
- SqlParameter[] param = new SqlParameter[]
- {
- new SqlParameter("@TeachClassID",enOptionalCourseScheduleLink.TeachClassID),//虛擬班ID
- new SqlParameter("@RoomID",enOptionalCourseScheduleLink.RoomID),//房間ID
- new SqlParameter("@WorkDay",enOptionalCourseScheduleLink.WorkDay),//星期
- new SqlParameter("@ClassBegin",enOptionalCourseScheduleLink.ClassBegin),//開始時間(如:上午第一節)
- new SqlParameter("@ClassEnd",enOptionalCourseScheduleLink.ClassEnd)//結束時間
- };
- //SQL語句類型
- CommandType cmdType = CommandType.Text;
- //SQLHELPER函數返回值
- blnIsResult = sqlHelper.ExecNoSelect(strSQL, param, cmdType, sqlCon, sqlTran);
- //返回函數值
- return blnIsResult;
- }
SqlHelper中關於事務的代碼
- #region 執行sql語句(事務中使用)
- /// <summary>執行sql語句(事務中使用)
- /// 執行sql語句(事務中使用)
- /// </summary>
- /// <param name="cmdText">在事務中執行的某個SQL語句或存儲過程</param>
- /// <param name="paras">參數集合</param>
- /// <param name="cmdType">命令類型</param>
- /// <param name="sqlConn">數據庫連接</param>
- /// <param name="sqlTran">事務</param>
- public Boolean ExecNoSelect(string cmdText, SqlParameter[] paras, CommandType cmdType, SqlConnection sqlConns, SqlTransaction sqlTran)
- {
- try
- {
- //實例化數據庫命令SqlCommand
- sqlCmd = new SqlCommand(cmdText, sqlConns);
- //命令類型:存儲過程or SQL語句
- sqlCmd.CommandType = cmdType;
- //添加參數
- sqlCmd.Parameters.AddRange(paras);
- //事務
- sqlCmd.Transaction = sqlTran;
- //定義事務執行結果
- int intResult = sqlCmd.ExecuteNonQuery();
- //執行事務:大於0返回true,否則返回false。
- if (intResult > 0)
- {
- //事務執行成功
- return true;
- }
- else
- {
- //事務執行失敗
- return false;
- }
- }
- catch (Exception ex)
- {
- //拋出異常
- throw ex;
- }
- }
- #endregion