1. 程式人生 > >mysql的悲觀鎖和樂觀鎖

mysql的悲觀鎖和樂觀鎖

1.需求分析

    專案上線後,在併發的情況,資料庫會插入重複的記錄;在這種情況,mysql的悲觀鎖或樂觀鎖可以用來實現程式碼邏輯的併發控制。

 2.悲觀鎖

①悲觀鎖,屬於排它鎖;當事務在操作資料時,它會把這部分資料進行鎖定,直到操作完畢後再解鎖,然後其他事務操作才可操作這部分的資料,這可以防止其他事務讀取或修改表中的資料;大多數情況下,悲觀鎖依靠資料庫的鎖機制實現排它性。

悲觀鎖的應用例項:

②synchronized屬於典型的悲觀鎖,通過同步程式碼塊將需要鎖住的邏輯鎖住,當該事務操作完成後,後續的事務方可執行該邏輯

 synchronized (ServiceAutoOverTimeJob.class
){ if(!serviceIsOverTime.equals("1") && serviceStauts.equals("1") && serviceEnabled.equals("1") && publishFree.equals("0")){//待接單,服務沒超時,可用狀態,付了車票錢 //超時單 pinCarMapper.setServiceTimeOut(serviceId); String orderId = businessOrderMapper.findOrderIdByServiceId(serviceId); PinCar pinCar = pinCarMapper
.selectByPrimaryKey(serviceId); JSMSCode.setJSMSCodeByChannel(0); // 生成支付訂單 String freeLose = pinCarMapper.getIsFreeLoseService(serviceId); String userId = pinCarMapper.getUserIdByServiceId(serviceId);//釋出者 String whoPublish = pinCarMapper.getServicePublishBy(serviceId); String mobile = userMapper.findMobileById(userId);
//使用者手機 String total_amount; String body; if(whoPublish.equals("1")){ //1:表示車主釋出 //剩餘座位的爽約金 Double restLoseAmount = pinCarMapper.getLoseAccountByServiceId(serviceId); Double rest = PublishAmountUtil.getdoubleAmount(restLoseAmount); total_amount = String.valueOf(rest); body = "車主待接單服務超時爽約金退還"; }else{ //0:表示乘客 total_amount = pinCarMapper.getTicketAmountByServiceId(serviceId); body = "乘客待接單服務超時"; } //返還服務釋出者釋出的金額 Integer increaseAmount = accountMapper.updateAmount(userId,total_amount); //獲取訂單號 String orderCode = businessOrderMapper.findOrderCodeById(orderId); // 生成服務釋出者的錢包流水 Double ticketAmount = this.accountMapper.findAmountByUserId(userId); AccountFlow ticketflow = AccountFlow.newBuilder().setUserId(userId).setOrderCode(orderCode) .setBody(body).setIsInflow("1").setTotal_amount(total_amount).setRemainAmount(ticketAmount.toString()) .build(); Integer insertAccountFlow = this.accountFlowMapper.insert(ticketflow.toMap()); // 手動資料回滾 if (increaseAmount != 1 || insertAccountFlow != 1) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } }else if(publishFree.equals("1")){ //免車票釋出 //超時單 pinCarMapper.setServiceTimeOut(serviceId); } }

類似上述情況運用悲觀鎖,該程式的併發效能顯然降低了,同時在高併發的情況會十分消耗mysql效能,悲觀鎖多用於訪問頻率不是很多的需求場景;

③select ... for update

SELECT * FROM yivi_sys_user WHERE id = 1 FOR UPDATE 

當使用了select ... for update的方式後,這樣就通過資料庫實現了悲觀鎖。此時在user表中id為1的那條資料就被悲觀鎖鎖定了,其他的事務必須等待該次事務提交完畢之後才能執行,這樣我們也可以保證當前的資料不會被其他事務修改

3.樂觀鎖

  樂觀鎖(Optimistic Lock), 顧名思義,就是樂觀的認為別人不會修改資料,所以每次拿資料的時候不會上鎖,但是在更新的時候會它檢查下是否有人去更新這個資料,可以使用資料版本記錄機制來實現鎖。樂觀鎖適用於多讀的應用型別,這樣可以提高系統的併發量。樂觀鎖的實現主要通過程式碼邏輯實現,跟mysql的鎖機制沒有半毛錢的關係。

樂觀鎖的應用例項

①在待鎖的資料表內新增一個version欄位或時間戳


②更新資料的sql

<update id="updateRedPacketStatus" parameterType="java.util.Map">
UPDATE
     yivi_red_packet
    SET
     packet_status=1,
     packet_version = packet_version + 1,
     packet_update_time = now()
    WHERE
     packet_id = #{packetId}
    AND
     packet_version = #{version}
</update>

③程式碼邏輯實現樂觀鎖

params.put("version","0"); //樂觀鎖控制併發
Integer updateResult = this.redPacketMapper.updateRedPacketStatus(params);
if(updateResult > 0){
    //資料更新操作
}else{
    //獲取鎖失敗
}

每次資料更新後,version的值會增加1;只有傳入的version值等於資料庫記錄的version值時,該事務才能對資料進行更新操作,其他的事務一律遮蔽在外,這就實現了所謂的“樂觀鎖”。

好了,我是張星,歡迎加入博主技術交流群,群號:313145288

相關推薦

MySQL數據庫同步之悲觀樂觀

我們 測試 http 鎖定 以及 再次 否則 即使 name 測試需要:本地開兩個測試窗口 悲觀鎖 悲觀鎖它指的是對數據被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,在整個數據處理過程中,將數據處於鎖定狀態。悲觀鎖的實現,往往依靠數據庫提供的

mysql悲觀樂觀

一、悲觀鎖 1、排它鎖,當事務在操作資料時把這部分資料進行鎖定,直到操作完畢後再解鎖,其他事務操作才可操作該部分資料。這將防止其他程序讀取或修改表中的資料。 2、實現:大多數情況下依靠資料庫的鎖機制實現 一般使用 select ...for update

36、談談MySQL支援的事務隔離級別,以及悲觀樂觀的原理應用場景?

目錄 今天我要問你的問題是,談談 MySQL 支援的事務隔離級別,以及悲觀鎖和樂觀鎖的原理和應用場景? 典型回答 考點分析 知識擴充套件 一課一練 在日常開發中,尤其是業務開發,少不了利用 Java 對資料庫進行基本的增刪改查等資料操作,這也是 Java 工程師的必備技能

mysql悲觀樂觀

1.需求分析    專案上線後,在併發的情況,資料庫會插入重複的記錄;在這種情況,mysql的悲觀鎖或樂觀鎖可以用來實現程式碼邏輯的併發控制。 2.悲觀鎖①悲觀鎖,屬於排它鎖;當事務在操作資料時,它會把這部分資料進行鎖定,直到操作完畢後再解鎖,然後其他事務操作才可操作這部分的

MySql悲觀樂觀總結

現在我有一個購買商品的需求,我們知道當我們購買商品時,後臺會進行減庫存和增加購買記錄的操作。我們分別在無鎖和樂觀鎖和悲觀鎖進行相應的程式碼演示來說明問題。     建表語句如下: CREATE TABLE `stock` ( `id` int(11) unsigned

悲觀樂觀

mysql鎖有兩種機制:悲觀鎖和樂觀鎖。悲觀鎖 悲觀鎖,鎖如其名,他對世界是悲觀的,他認為別人訪問正在改變的數據的概率是很高的,所以從數據開始更改時就將數據鎖住,直到更改完成才釋放。一個典型的倚賴數據庫的悲觀鎖調用: select * from account where name=”Erica”

Hibernate 再接觸 悲觀樂觀

package his sts nsa comm pen hibernate UNC ann 為什麽取1248 二進制 CRUD 移位效率高 在並發和效率選擇一個平衡點 一般不會考慮幻讀 因為我們不會再一個事務裏查詢兩次,(只能設置為seralizable) 悲觀鎖

hibernate機制有什麼用?Hibernate的悲觀樂觀機制

有些業務邏輯在執行過程中要求對資料進行排他性的訪問,於是需要通過一些機制保證在此過程中資料被鎖住不會被外界修改,這就是所謂的鎖機制。 Hibernate支援悲觀鎖和樂觀鎖兩種鎖機制。悲觀鎖,顧名思義悲觀的認為在資料處理過程中極有可能存在修改資料的併發事務(包括本系統的其他事務或來自外部系統的

深入瞭解探索資料庫的悲觀樂觀

 在資料庫的鎖機制中介紹過,資料庫管理系統(DBMS)中的併發控制的任務是確保在多個事務同時存取資料庫中同一資料時不破壞事務的隔離性和統一性以及資料庫的統一性。 樂觀併發控制(樂觀鎖)和悲觀併發控制(悲觀鎖)是併發控制主要採用的技術手段。 無論是悲觀鎖還是樂觀鎖,都是人們定義出來

資料庫的悲觀樂觀

一 :悲觀鎖(Pessimistic Locking)  悲觀鎖,正如其名,它指的是對資料被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定 狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提

悲觀樂觀的簡單瞭解

悲觀鎖:悲觀鎖是由資料庫提供的,用於防止資料庫併發控制造成的異常。   實現悲觀鎖:在要進行加鎖的事務中的sql語句末加上 for update。   悲觀鎖正如他的名字一樣,比較悲觀,他在加鎖過程中,不允許任何事務進行查詢或增刪改。       樂觀鎖:樂觀鎖是由邏

java多執行緒系列3:悲觀樂觀

1.悲觀鎖和樂觀鎖的基本概念 悲觀鎖: 總是認為當前想要獲取的資源存在競爭(很悲觀的想法),因此獲取資源後會立刻加鎖,於是其他執行緒想要獲取該資源的時候就會一直阻塞直到能夠獲取到鎖; 在傳統的關係型資料庫中,例如行鎖、表鎖、讀鎖、寫鎖等,都用到了悲觀鎖。還有java中的同步關鍵字Synchroniz

hibernate面試題之機制有什麼用?簡述Hibernate的悲觀樂觀機制

有些業務邏輯在執行過程中要求對資料進行排他性的訪問,於是需要通過一些機制保證在此過程中資料被鎖住不會被外界修改,這就是所謂的鎖機制。 Hibernate支援悲觀鎖和樂觀鎖兩種鎖機制。悲觀鎖,顧名思義悲觀的認為在資料處理過程中極有可能存在修改資料的併發事務(包括本

資料庫悲觀樂觀使用Mybatis

以下是轉載的oracle和Mysql兩種資料庫悲觀鎖和樂觀鎖機制及樂觀鎖實現方式: 一、Oracle Oracle資料庫悲觀鎖與樂觀鎖是本文我們主要要介紹的內容。有時候為了得到最大的效能,一般資料庫都有併發機制,不過帶來的問題就是資料訪問的衝突。為了解決這個問題,大多數資

synchronizedlock的區別;悲觀樂觀的區別

synchronized和lock的區別:  1.用法不一樣。synchronized既可以加在方法上,也可以載入特定的程式碼塊上,括號中表示需要鎖的物件。而Lock需要顯示地指定起始位置和終止位置。synchronzied是託管給jvm執行的,Lock鎖定是通過程式碼實現

Spring Boot+SQL/JPA實戰悲觀樂觀

最近在公司的業務上遇到了併發的問題,並且還是很常見的併發問題,算是低階的失誤了。由於公司業務相對比較複雜且不適合公開,在此用一個很常見的業務來還原一下場景,同時介紹悲觀鎖和樂觀鎖是如何解決這類併發問題的。 公司業務就是最常見的“訂單+賬戶”問題,在解決完公司問題後,轉頭一想,我的部落格專案Fame中也有同樣

悲觀樂觀解決事務丟失跟新問題

事務丟失更新:A,B兩個事務通過id獲取資料,name:lisi,money:1000 首先,A事務修改name,把lisi變為zhangsan,然後提交事務。此時,B事務中不受A事務的影響,即B事務中的name還是lisi,此時如果B事務改變money為2000,然後提交事務。最後資料庫的資料

redis的 悲觀樂觀的區別

悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作

Java機制 悲觀樂觀

鎖的存在,是為了解決在併發環境下,資料的一致性問題。鎖機制保證了程式不會出現,髒讀,衝突等情況。 先介紹下,悲觀鎖和樂觀鎖的基本描述。 悲觀鎖 正如其名,當出現在多使用者的併發環境中時, 它對資料出現併發衝突,持保守態度(悲觀)。它假定一定出現衝突,所以在

悲觀樂觀的區別及應用場景

資料的鎖定分為兩種,第一種叫作悲觀鎖,第二種叫作樂觀鎖。 1、悲觀鎖,就是對資料的衝突採取一種悲觀的態度,也就是說假設資料肯定會衝突,所以在資料開始讀取的時候就把資料鎖定住。【資料鎖定:資料將暫時不會得到修改】 2、樂觀鎖,認為資料一般情況下不會造成衝突,所以在資料進行提交