Mysql 5 5 53 事務與併發測試

2021-10-19 19:54:16 字數 4172 閱讀 6751

1.在事務中使用查詢遇上併發的情況

(1)執行緒1事務開啟,執行緒2查詢資料

原始資料:tea_name=』bbb』;

執行緒1:start transaction;

執行緒1:select * from t_a_tea where tea_id=1;

執行緒2:select * from t_a_tea where tea_id=1;

結果:bbb(tea_id=1時tea_name的資料)

結論:查詢不會觸發mysql共享鎖(讀鎖)

(2)執行緒1事務已開啟,執行緒1查詢資料,執行緒2修改資料,執行緒1讀取資料

原始資料:tea_name=』bbb』;

執行緒1:start transaction;

執行緒1:select * from t_a_tea where tea_id=1;

執行緒2:update t_a_tea set tea_name=『ccc』 where tea_id=1;

執行緒1:select * from t_a_tea where tea_id=1;

結果:bbb(tea_id=1時tea_name的資料)

結論:查詢不會觸發mysql排他鎖(寫鎖),但是事務的隔離性會導致查詢到錯誤的資料

(3)執行緒1事務已開啟,執行緒2修改資料,執行緒1讀取資料

原始資料:tea_name=』bbb』;

執行緒1:start transaction;

執行緒2:update t_a_tea set tea_name=『eee』 where tea_id=1;

執行緒1:select * from t_a_tea where tea_id=1;

結果:eee(tea_id=1時tea_name的資料)

結論:當資料沒有在事務中被執行sql語句時,不會觸發事務的隔離性,因此在事務中查詢不會得到錯誤的資料

(4)執行緒1事務已開啟,執行緒1修改資料,執行緒1讀取資料

原始資料:tea_name=』bbb』;

執行緒1:start transaction;

執行緒1:update t_a_tea set tea_name=『eee』 where tea_id=1;

執行緒1:select * from t_a_tea where tea_id=1;

結果:eee(tea_id=1時tea_name的資料)

結論:在同乙個執行緒中不存在事務的隔離性,因此使用查詢操作不會得到錯誤的結果

2.在事務中使用更新遇上併發的情況

(1)執行緒1事務開啟,執行緒1更新資料,執行緒2更新資料,執行緒1提交資料

原始資料:tea_name=』bbb』;

執行緒1:start transaction;

執行緒1:update t_a_tea set tea_name=『ccc』 where tea_id=1;

執行緒2:update t_a_tea set tea_name=『eee』 where tea_id=1;

執行緒1:commit;

結果:eee(tea_id=1時tea_name的資料)

結論:更新時觸發排他鎖(寫鎖),執行緒1執行完查詢執行緒2才繼續執行

(2)執行緒1事務開啟,執行緒1更新資料,執行緒2查詢資料

原始資料:tea_name=』bbb』;

執行緒1:start transaction;

執行緒1:update t_a_tea set tea_name=『ccc』 where tea_id=1;

執行緒2:select * from t_a_tea where tea_id=1;

結果:bbb(tea_id=1時tea_name的資料)

結論:更新時不會觸發共享鎖(讀鎖),事務的隔離性使執行緒1提交之前執行緒2查詢不到更新後的資料

3.在事務中使用插入遇上併發情況

因為插入語句不涉及已存在語句被鎖情況,因此測試當其中一條資料回滾時對主鍵id的影響

(1)執行緒1事務開啟,執行緒1新增一條資料,執行緒2新增一條資料,執行緒1回滾

新增一條資料,測試自增是否正常

insert into t_a_tea(tea_name) values (『qqq』);

此時資料狀態:

自增狀態正常,下一條主鍵狀態應為3

執行緒1:start transaction;

執行緒1:insert into t_a_tea(tea_name) values (『qqq』);

執行緒2:insert into t_a_tea(tea_name) values (『qqq』);

執行緒1:rollback;

執行緒2:commit;

結果:

結論:在事務沒有提交的情況下,事務中使用新增操作會影響主鍵id的自增,同理可得,當執行緒2開啟事務新增一條資料時使用回滾,會影響下一條資料的主鍵id

4.在事務中使用刪除遇上併發情況

(1)執行緒1開啟事務,執行緒1刪除tea_id=4的資料,執行緒2刪除tea_id=4資料

執行緒1:start transaction;

執行緒1:delete from t_a_tea where tea_id=4;

執行緒2:delete from t_a_tea where tea_id=4;

結果:執行緒2等待執行緒1提交後執行刪除操作

結論:刪除時會觸發事務的排他鎖(寫鎖)

(2)執行緒1開啟事務,執行緒1刪除tea_id=2的資料,執行緒2更新tea_id=2資料

執行緒1:start transaction;

執行緒1:delete from t_a_tea where tea_id=2;

執行緒2:update t_a_tea set tea_name=『eee』 where tea_id=2;

結果:執行緒2等待執行緒1提交後執行更新操作

結論:刪除時會觸發事務的排他鎖(寫鎖),且更新和刪除操作都受排他鎖影響

(3)執行緒1開啟事務,執行緒1刪除tea_id=2的資料,執行緒查詢tea_id=2資料

執行緒1:start transaction;

執行緒1:delete from t_a_tea where tea_id=2;

執行緒2:select * from t_a_tea where tea_id=2;

結果:

結論:刪除時不會觸發事務的共享鎖(讀鎖)

總結由測試結果可得:

1.當事務執行更新刪除時會觸發事務的排他鎖(寫鎖),是與之對應的資料無法進行更新刪除操作,但是不影響查詢操作,查詢的結果為未提交資料前的資料

2.當事務執行新增操作時,無論最後有無回滾,自增主鍵都會+1

3.當資料執行查詢操作時,由於事務的隔離性,當執行緒1使用查詢操作時觸發事務,不會觸發事務的排他鎖,此時執行緒2執行更新操作,執行緒1再查詢語句就會出現查詢不到執行緒2執行更新操作後的資料

可推測模型:

應用場景

限量搶購

錯誤案例:

表:t_a_shop,存放商品,當shop表中的num為0時,商品買完

//開啟事務

start transaction;

//獲取當前商品數

int shopnum = select num from t_a_shop where shop_id=?;

//得到應有商品數

shopnum -= shopnum;

//更新商品數

update t_a_shop set num=shopnum where shop_id=?

//提交事務

commit;

錯誤原因:當事務開啟時使用查詢並不會將shop_id=?的資料加排他鎖(寫鎖),因此在得到查詢結果時,其他執行緒還可以對資料進行更改,因此在事務提交時可能會使資料發生。

解決方式:update t_a_shop set num=num-1 where shop_id=?利用更新會加排他鎖的特性,保證事務的穩定執行

Mysql 邏輯架構 併發與事務

2 併發控制 3 事務 4 多版本併發控制 參考 每個客戶端連線都會在服務程序中擁有乙個執行緒,這個連線的查詢只會在這個單獨的執行緒找那個執行,該執行緒只能夠在某個cpu核心或者cpu中執行 對mysql進行查詢時,mysql會解析查詢,並建立內建資料介面 解析樹 然後對其進行各種優化 重寫查詢 決...

併發與事務

本部落格只是在開發過程中,對遇到的多執行緒問題的思考,如何在保證資料正確的前提下,提高效能。我覺得併發要考慮兩個問題 在io層次,併發鏈結數過多例如c10k,c10m的問題,是通過reactor 模式解決?例如開源的網路庫都是使用單執行緒io復用 非阻塞的思想解決,最優!還是通過乙個連線對應乙個執行...

事務與併發

一 首先我們先來看段 conn.setautocommit false int count1 utilconn.updatedata conn,update dict cost subj set is hr 0 if count1 1 else 這斷 經過資料庫跟蹤是 img set implici...