一、引言
MySQL事務主要用來處理資料量大、資料複雜度高的資料操作,最經典的使用場景是銀行的轉賬:需要先從銀行賬戶A中取出錢,然後再存入銀行賬戶B中,如果中間出現問題,而沒有事務的保證,那麼就會出現B收不到錢,而A支出錢又回不到自己的賬戶的嚴重問題,那麼有了事務機制,這個問題就解決了。
總之,事務是處理crid中cid三種操作,要不全執行要不全不執行==
二、基本概念
2.1 事務特點
1、A(Atomicity),即事務的原子性
一組事務操作,要麼都成功,要麼都撤回。
2、C(Consistency),即事務的穩定性
有非法資料操作,如:外鍵限制,事物撤回。
3、I(Isolation),即事務的隔離性
事務是獨立運作的,一個事務的操作如果影響了另一個事物,那麼另一個事務就會撤回執行,要做到事務100%的隔離,需要犧牲速度和性能。
4、D(Durability),即事務的可靠性
當資料庫崩潰之後,InnoDB資料庫表驅動會利用日志檔案進行資料的重構修改,需要注意的是:安全性和性能速度不可兼得。
2.2 事務隔離
1、并發時遇到的問題
在事務并發操作時,經常出現一些問題,這些問題可用幾個術語名詞描述:
A、髒讀
一個事務讀取了另一個事務并發寫的未送出的資料,比如:事務A讀取了事務B寫入的資料,但是B事務并未送出,後來其撤銷了修改,此時事務A就讀取了不該讀取的資料。
B、幻讀
一個事務重複讀取資料,在獲得的資料行中發現某些資料是其它事務最近操作的資料,比如:事務A反複執行查詢語句查詢資料表,而這時另一事務B正在操作該表,恰好的是事務B操作的資料正符合事務A查詢的條件,而事務A再讀取時,發現結果集發生了變化,這在并發事務時經常出現。
C、不可重複讀
一個事務重複讀取之前讀取過的資料,後發現讀取的資料被另一個事務所修改,比如:事務A反複讀取指定的資料,而此時事務B正好操作該資料,當事務A再次查詢時,發現之前讀取的資料已經變化。
注:
上面事務并發出現的問題,可以通過設定事務的隔離來處理,但不能完全依賴事務隔離,而是應該在應用程式中恰當的使用鎖來控制并發通路,兩者的結合是解決的問題關鍵。
2、事務的隔離級别
事務隔離級别分為4種:
READ UNCOMMITED // 允許幻讀,髒讀及不可重複讀;
READ COMMITED // 允許幻讀和不可重複讀,不允許髒讀;
REPEATABLE READ // 允許幻讀,不允許髒讀和不可重複讀;
SERIALIZABLE READ // 不允許幻讀,髒讀及不可重複讀;
注:
Mysql預設的是REPEATABLEREAD級别。另外,随着事務的隔離級别越高,并發執行的性能就越低,是以适當選擇級别并結合業務需求來標明級别設定。
三、代碼使用
C#中的使用
public static bool ExcuteTransactionSQL(List<string> strSQL)
{
using (MySqlConnection conn = new MySqlConnection(strConn))
{
conn.Open();
MySqlTransaction transaction = conn.BeginTransaction();
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.Transaction = transaction;
try
{
for (int n = 0; n < strSQL.Count; n++)
{
string strsql = strSQL[n];
if (strsql.Trim().Length > 1)
{
cmd.CommandText = strsql;
cmd.ExecuteNonQuery();
}
}
cmd.ExecuteNonQuery();
transaction.Commit();
conn.Close();
return true;
}
catch
{
transaction.Rollback();
conn.Close();
return false;
}
}
}
四、總結
- 事務的使用場景
- 事務ACID
- 事務的隔離
- 事務在代碼中的使用