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


程序大概代碼。

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             }
View Code

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM