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

2022-02-25 09:12:44 字數 2049 閱讀 8934

程式大概**。

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);

3con.open();

4 random r = new

random();

5int n = r.next(100);6

7string sql = "

update nc_a set name='gfeng

"+n.tostring()+"

' where id=14";

8 mysqlcommand com = new

mysqlcommand(sql, con);

9 mysqltransaction tran =con.begintransaction();

10try

1121

else

2225

26con.close();27}

28catch

29

view code

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

多執行緒併發更新同一條記錄

有乙個任務表,每個任務有n個事項要併發處理,每個事項完成時需要更新已完成數,即finished 1,當n個事項全部處理完成即整個任務完成時需要做任務的統計工作。資料庫通過行級鎖來保證併發更新準確性,測試 如下 publicclass concurrency conn.commit catch exc...

更新最後一條記錄

修改最後一條記錄 update userinfo set userid 55 where 1 order by userid desc limit 1 刪除第一條記錄 delete from userinfo where 1 order by userid limit 1 mysql 總結 在寫這段...

go orm如何多個協程並行更新一條記錄

最近遇到乙個問題,兩個go協程裡要同時更新同乙個記錄的不同字段 buy和sell 踩了一天的坑,才找到正確的方式。首先想到的是使用 o orm.neworm o.update rices 但是發現會出現buy或者sell乙個為空的情況。之後再這裡看到可以使用這種方式 建立orm物件 o orm.ne...