某些業務需要更新某一個表的多個字段,很可能更新的結果跟理想值不一致。簡單來講就是執行類似下面的sql會出什么結果?
update test set a = a+1,b=a+1 where id =2
mysql創建表的sql語句、我們來模擬一下上面的sql環境,我們創建一個test表,并使用innodb存儲引擎。
create table test (id int,a int,b int,primary key(id));
增加三行數據
insert into test values (1,10,100),(2,20,200),(3,30,300)
mysql 閃回。進行修改多個字段
update test set a = a+1,b=a+1 where id =2
修改的條件是id=2,為啥修改的結果是(2,21,22),不應該是(2,21,21)嗎?是不是很多人以為修改的結果是(2,21,21),是不是感覺數據是亂的,如果數據少,改回去還算省事,關鍵數據量很多,改的工作量就大了,還容易出錯。
sql和mysql學哪個,因為 update 是當前讀,讀取的是記錄數據的最新版本,
update test set a = a+1,b=a+1 where id =2
update a=a+1 因為要做當前讀 現在a =20 +1 后 a=21 ,保證最新值,再做 b=a+1
也需要讀到a值的最新的值 還要加鎖, 現在a的值已經變成21, 再加1就變成22,
那么如果我想按照我們的理想值更新出結果,那要怎么做呢?
可以把 a 列暫存在一個臨時變量里
select?a?into?@a?from?test where?a=2;
再執行修改
update?test?set?a=@a+1,b=@a+1?where?a=@a;
結果就會是(2,21,21)了
執行select的時候,innodb默認會執行快照讀,快照讀,也就是讀取快照的數據,數據雖然是一致的,但是數據是歷史數據。
快照讀:只是簡單的 select ,不包括 select … lock in share mode, select … for update
當你執行這幾個操作的時候默認會執行當前都會加鎖,也就是會讀取最新的記錄,也就是別的事務提交的數據你也可以看到。
update 執行當前讀,然后把返回的數據加鎖,之后執行update。
加鎖是防止別的事務在這個時候對這條記錄做什么,默認加的是排他鎖,也就是只允許讀,其他都不可以,這樣就可以保證數據不會出錯了。
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态