並行事務同時更新同一條記錄

程序大概代碼。mysql

sql語句sql

 

 

首先調試程序,等程序斷下來以後,在瀏覽器從新發起一次請求,模擬雙線程。這時調試窗口有線程(ps:這裏用到的是mysql自帶的鏈接池)瀏覽器

 事務開始但還沒更新該記錄時,該行還未被鎖定,這是還能夠更新dom

這時6號線程下一步就執行更新操做了ide

6號線程執行完以後,因爲事務ID爲14的記錄被鎖定,能夠看到已經不能修改了,在排隊等待事務關閉,若是等待太久直接取消此次操做性能

這時8號線程也在執行更新ID爲14的操做,可是因爲上一個事務未關閉,致使被鎖,在排隊等待。spa

能夠看到mysql取消操做了。線程

已經異常了,並且鏈接已經關閉了3d

這時手動釋放事務,因爲是鏈接池,調用Close()並非真正關閉鏈接只是放回鏈接池。因此要釋放事務,否則下次得到該鏈接時會出錯。並且還會致使死鎖。調試

最後,總結並行事務第一個事務會鎖住更新的記錄,下一個事務操做(更新或刪除)該記錄時排隊等待上一個事務釋放鎖,若是等待過長會取消操做,而且拋出異常,捕獲異常進行相應的操做回滾事務或關閉鏈接釋放鎖,否則會致使死鎖。而且上一個事務提交以後,下一個事務的回滾不會影響到上一個事務的操做。

 1 string connString = "Server=localhost;Database=test;Uid=root;Pwd=root;Charset=utf8;pooling=true;Min Pool Size=2;Max Pool Size=20;";
 2             MySqlConnection con = new MySqlConnection(connString);
 3             con.Open();
 4             Random r = new Random();
 5             int n = r.Next(100);
 6            
 7             string sql = "update Nc_A set name='gfeng"+n.ToString()+"' where id=14";
 8             MySqlCommand com = new MySqlCommand(sql, con);
 9             MySqlTransaction tran = con.BeginTransaction();
10             try
11             {
12                 int rowcount = com.ExecuteNonQuery();
13                 int k = 0;
14                 int jk = 0;
15                 int jk2 = 0;
16                 if (HttpContext.Cache["n"] == null)
17                 {
18                     tran.Commit();
19                     HttpContext.Cache["n"] = n;
20                 }
21                 else
22                 {
23                     tran.Rollback();
24                 }
25 
26                 con.Close();
27             }
28             catch
29             {
30                 con.Close();
31             }
View Code

固然不是更新同一條記錄是各不影響的。主要仍是要理解鎖和事務的機制(之間是有區別的,用事務比用鎖性能要低,畢竟要懸掛事務用於回滾或提交)。

相關文章
相關標籤/搜索