1. 程式人生 > >web併發,for update

web併發,for update

一、前言

針對併發,老生常談了。目前一個通用的做法有兩種:鎖機制:1.悲觀鎖;2.樂觀鎖。

但是這篇我主要用於記錄我這次處理的經歷,另外希望能看的大神,大牛,技師者,學長,兄長,大哥們能在評論中發表自己的看法和解決技巧等。

二、故事是這樣的

一個表,暫且叫 wallet,其中3個欄位是 金額。初始值為0,如下圖所示:
image

然後我們寫了一個極為簡單的Controller,並寫了下面的Service程式碼:

123456789101112131415@Overridepublic void testLock(int lockId){Wallet wallet = walletMapper.selectByPrimaryKey(4);
BigDecimal one = new BigDecimal(1.00);BigDecimal two = new BigDecimal(2.00);BigDecimal three = new BigDecimal(3.00);wallet.setWalletAmount(wallet.getWalletAmount().add(one));wallet.setWalletAvailableAmount(wallet.getWalletAvailableAmount().subtract(two));wallet.setOldAmount(wallet.getOldAmount().add(three));     
walletMapper.updateByPrimaryKeySelective(wallet);}

就簡單的通過主鍵讀取到一個物件,注意這個物件是沒加鎖的。也就是說,所對應的SQL如下:

1234SELECT<include refid="Base_Column_List" />FROM walletWHERE wallet_id = #{walletId,jdbcType=INTEGER}

我這邊是MyBiatis,大家應該看得懂的。然後一個增加1 一個減少2 一個增加 3。

三、測試是這樣

我用了Web應用壓力測試工具:Boomhttps://github.com/rakyll/boom Go編寫的HTTP(S)負載生成器,ApacheBench(AB)的替代工具。Boom是一個微型程式,能夠對Web應用程式進行負載測試。它類似於 Apache Bench ,但在不同的平臺上有更好的可用性,安裝使用也比較簡單。

簡單使用方式如下:

123456789101112131415161718Options:-n  Number of requests to run.-c  Number of requests to run concurrently. Total number of requests cannotbe smaller than the concurency level.-q  Rate limit, in seconds (QPS).-o  Output type. If none provided, a summary is printed."csv" is the only supported alternative. Dumps the responsemetrics in comma-seperated values format.-m  HTTP method, one of GET, POST, PUT, DELETE, HEAD, OPTIONS.-h  Custom HTTP headers, name1:value1;name2:value2.-d  HTTP request body.-T  Content-type, defaults to "text/html".-a  Basic authentication, username:password.-allow-insecure Allow bad/expired TLS/SSL certificates.

所以我就如圖進行壓力測試,可見這個小工具還挺美的,這裡我連線數1000,併發數100
image
可見後臺程式報錯了。什麼錯誤呢?

1Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction

原來併發導致update死表了。資料庫的資料不用看了肯定是錯誤的。

四、FOR UPDATE的使用

先補一下其知識:利用select * for update 可以鎖表/鎖行。自然鎖表的壓力遠大於鎖行。所以我們採用鎖行。什麼時候鎖表呢?

假設有個表單products ,裡面有id跟name二個欄位,id是主鍵。
例1: (明確指定主鍵,並且有此筆資料,row lock)
SELECT * FROM wallet WHERE id=’3′ FOR UPDATE;
例2: (明確指定主鍵,若查無此筆資料,無lock)
SELECT * FROM wallet WHERE id=’-1′ FOR UPDATE;
例2: (無主鍵,table lock)
SELECT * FROM wallet WHERE name=’Mouse’ FOR UPDATE;
例3: (主鍵不明確,table lock)
SELECT * FROM wallet WHERE id<>’3′ FOR UPDATE;
例4: (主鍵不明確,table lock)
SELECT * FROM wallet WHERE id LIKE ‘3’ FOR UPDATE;

因此我們更新了下Service層的Mapper方法:

123456789101112131415@Overridepublic void testLock(int lockId){Wallet wallet = walletMapper.selectForUpdate(4);BigDecimal one = new BigDecimal(1.00);BigDecimal two = new BigDecimal(2.00);BigDecimal three = new BigDecimal(3.00);wallet.setWalletAmount(wallet.getWalletAmount().add(one));wallet.setWalletAvailableAmount(wallet.getWalletAvailableAmount().subtract(two));wallet.setOldAmount(wallet.getOldAmount().add(three));     walletMapper.updateByPrimaryKeySelective(wallet);}

所對應的SQL如下:

12345

相關推薦

web併發for update

一、前言針對併發,老生常談了。目前一個通用的做法有兩種:鎖機制:1.悲觀鎖;2.樂觀鎖。但是這篇我主要用於記錄我這次處理的經歷,另外希望能看的大神,大牛,技師者,學長,兄長,大哥們能在評論中發表自己的看法和解決技巧等。二、故事是這樣的一個表,暫且叫 wallet,其中3個欄位

Oracle編輯數據時提示:這些查詢結果不可更新請使用ROWI或者SELECT……FOR UPDATE獲得可更新結果

對數 date 一個 更新 bsp ron 我們 pda from 我們在對Oracle數據庫進行操作時,有時會在查詢完結果後想要對其中的某些數據進行操作,當我們點擊編輯(一個鎖標誌)是,會提示我們上述問題中的錯誤:這些查詢結果不可更新,請使用ROWI或者SELECT……F

JAVA架構師大型分散式高併發電商專案實戰效能優化叢集億級高併發web安全快取架構實戰

現任58到家技術委員會主席,高階技術總監,負責企業,支付,營銷、客戶關係等多個後端業務部門。本質,技術人一枚。網際網路架構技術專家,“架構師之路”公眾號作者。曾任百度高階工程師,58同城高階架構師,58同城技術委員會主席,58同城C2C技術部負責人。 內容介紹 1.大資

list的迭代器能解決併發問題,collection 的迭代器不能解決併發問題for可以解決併發問題

list的迭代器能解決併發問題,collection 的迭代器不能解決併發問題   為什麼list支援add,collection不支援   例如有兩個人同時新增第三個元素 list的迭代器能鎖定執行緒 只有等第一人新增完成才能進行第二個人新增 而 collection的迭代器卻不

mybatis 使用for update對資料進行行級鎖定

與Spring Date JPA中使用行級鎖一樣,都需要加上事務,並在查詢的時候加上for update。直接上程式碼: 資料庫表: create table t_pub_student( id int PRIMARY key auto_increment, code

SQL 聯合主鍵跨表刪除最小時間那條重複資料跨表 for UPdate

一、過濾出需要刪除的重複資料的ID select  aac001  from ei_app_recheck_citi_id inner join std_app on std_app.app_id=ei_app_recheck_citi_id.app_id where s

mysql事務select for update及資料的一致性處理

在MySQL的InnoDB中,預設的Tansaction isolation level 為REPEATABLE READ(可重讀) 在SELECT 的讀取鎖定主要分為兩種方式:   SELECT ... LOCK IN SHARE MODE    SELECT ... FOR UPDATE   這兩

mysql事務select for update及數據的一致性處理

use tro where strong 結束 mysql事務 mode evel 簡單的 在MySQL的InnoDB中,預設的Tansaction isolation level 為REPEATABLE READ(可重讀) 在SELECT 的讀取鎖定主要分為兩種方式:

ORACLE中更新資料PLSQL Developer中SELECT ... FOR UPDATE和 SELECT T.*,ROWID的區別

背景:ORACLE中更新少量資料時,在PLSQL  Developer中,一般用的語句是SELECT   FOR   UPDATE和SELECT   T.*,ROWID,這倆語句執行之後可以手動在查詢出來的資料中修改。例項背景:表名A,資料如下:  ACOL1    COL2

thinkphp中如何使用鎖的功能如何使用類似於mysql的for update功能?

Thinkphp的加鎖功能,我下面詳細說一下:    首先,資料庫型別要是InnoDB,其次,加鎖必須跟事務同時使用,還有,查詢的時候都必須帶鎖,比如: $user_mod->lock(true)->where(‘id=1’)->select();這個地方用

MySQL事務+FOR UPDATE解決併發操作資料庫

注意 FOR UPDATE 僅適用於InnoDB,且必須在事務區塊(BEGIN/COMMIT)中才能生效。由於InnoDB 預設是Row-Level Lock,所以只有「明確」的指定主鍵,MySQL 才會執行Row lock (只鎖住被選取的資料) ,否則MySQL 將會執行

updateupdate中無法用基於被更新表的子查詢You can't specify target table 'test1' for update in FROM clause.

子查詢 src nbsp spec tab can 技術分享 例如 bubuko update中無法用基於被更新表的子查詢,You can‘t specify target table ‘test1‘ for update in FROM clause. 情況如下: (

移動端WEB開發click,touch,tap事件淺析

func mousedown spa 手指 滑動 兼容性 over syntax ack 一、click 和 tap 比較 兩者都會在點擊時觸發,但是在手機WEB端,click會有 200~300 ms,所以請用tap代替click作為點擊事件。 singleTap和dou

Web公路新手上路! No.1

under html html4 oos http org bsp web tran <!DOCTYPE>   用於告訴瀏覽器用何種HTML標準去讀取指令。  HTML5:   <!DOCTYPE html>  HTML4.01 strict:

沒有第三方web服務怎麽運行php?

php web server 最近在搗鼓的時候,意外發現php自帶web server功能。於是就實驗了一下。 可以看到的是,php命令行模式下提供了以下參數:-S <addr>:<port> Run with built-in web server

for update造成的Oracle鎖表與解鎖

執行 lec 如果 pl/sql 查看 數據 system oracle log 我遇到的情況: 當使用select語句查詢表時,後面跟著for update , select * from table for update 當修改表中數據,但是沒有com

鎖定數據行 for updatefor update nowait

for update和for update nowait鎖定數據行select * from emp t where t.deptno=‘20‘ for update nowait;這樣就鎖定了emp表中deptno = 20的那行數據註意:通過for update鎖定後,這些行不能修改了,但是還可以查詢f

Spring Boot入門第二天:一個基於Spring Boot的Web應用使用了Spring Data JPA和Freemarker。

per pan let mysq 應用 posit ble host thead 今天打算從數據庫中取數據,並展示到視圖中。不多說,先上圖: 第一步:添加依賴。打開pom.xml文件,添加必要的依賴,完整代碼如下: <?xml version="1.0" enco

【轉載】MySQL事務以及SELECT ... FOR UPDATE的使用

商品 tail ase -a base 我們 evel erl tel MySQL中的事務,默認是自動提交的,即autocommit = 1; 但是這樣的話,在某些情形中就會出現問題:比如: 如果你想一次性插入了1000條數據,mysql會commit1000次的, 如果我

第三百二十四節web爬蟲scrapy模塊介紹與使用

通訊 通用 系列 python安裝 ide 調度器 功能 自動 優先 第三百二十四節,web爬蟲,scrapy模塊介紹與使用 Scrapy是一個為了爬取網站數據,提取結構性數據而編寫的應用框架。 其可以應用在數據挖掘,信息處理或存儲歷史數據等一系列的程序中。其最初是為了頁面