程序大概代碼。
sql語句
首先調試程序,等程序斷下來之后,在瀏覽器重新發起一次請求,模擬雙線程。這時調試窗口有線程(ps:這里用到的是mysql自帶的連接池)
事務開始但還沒更新該記錄時,該行還未被鎖定,這是還可以更新
這時6號線程下一步就執行更新操作了
6號線程執行完之后,由於事務ID為14的記錄被鎖定,可以看到已經不能修改了,在排隊等待事務關閉,如果等待過久直接取消這次操作
這時8號線程也在執行更新ID為14的操作,但是由於上一個事務未關閉,導致被鎖,在排隊等待。
可以看到mysql取消操作了。
已經異常了,而且連接已經關閉了
這時手動釋放事務,由於是連接池,調用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 }
當然不是更新同一條記錄是各不影響的。主要還是要理解鎖和事務的機制(之間是有區別的,用事務比用鎖性能要低,畢竟要懸掛事務用於回滾或提交)。