1. 程式人生 > >高併發與鎖(一)

高併發與鎖(一)

      DRP學習中,我們對可能引起併發操作的情況使用了鎖,這次先理論上看看併發控制與鎖的一些內容吧。

    併發控制

    在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會產生衝突。這就是併發性。典型的衝突有:


    1、丟失更新(Lost updates)
    一個事務的更新覆蓋了其它事務的更新結果,就是所謂的更新丟失。例如:使用者A把值從6改為2,使用者B把值從2改為6,則使用者A丟失了他的更新。


    2、髒讀(Dirty reads)
    當一個事務讀取其它完成一半事務的記錄時,就會發生髒讀取。例如:使用者A,B看到的值都是6,使用者B把值改為2,使用者A讀到的值仍為6。


    3、不可重複讀(Non-repeatable reads)
    當一個程序讀取了一筆資料後,另一個程序更新了同一筆資料,然後第一個程序再次讀取同一筆資料,卻得到了 與第一次讀取不同的結果。

    在事務A更新記錄之後(update Customers set Name = 'B' where Name = 'A'),事務B讀取相同記錄(select Name form Customers where Name = 'A'),但事務B拿到的是事務A更新之後的資料(Customers.Name的值為'B'),在事務B讀取記錄之後,事務A進行了事務回滾(Customers.Name的值為'A'),導致事務B的資料是不真實的。

    4、

幻讀(Phantoms)
    幻讀與髒讀的相似之處在於:兩者都是兩次讀取的結果不一致。
不同之處在於:幻讀是兩次讀取的記錄數量不一致,而髒讀是兩次讀取的記錄的資料不一致。
事務A讀取記錄之後(select * from Customers where Name like 'A%'),事務B又插入了符合事務A讀取條件的新記錄(insert into Customers(Name) values('AAA')),那麼當事務A再用相同條件讀取記錄時,得到的集合卻與上一次讀取不同(多了記錄)。

   解決方案:執行緒同步和加鎖

   通常我們解決併發問題使用同步和加鎖兩種方式。

   同步中,我們通過Java中的synchronized關鍵字來實現,但這樣通常會帶來效能和效率上的一些問題。

   這次,我們主要講解鎖。鎖機制中,我們可以根據不同情況使用悲觀鎖或樂觀鎖。

   悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
   對於悲觀鎖,我們可以提供一個值作為鎖的引數。比如一個鍵預設會被鎖定15秒。15秒過後,如果你還沒有手動的釋放鎖,那麼使程式自動的為你釋放。
   悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改資料)。但隨之而來的就是資料庫效能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。
   

   與之對應的--樂觀鎖:
   樂觀鎖(Optimistic Lock), 就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料。
   而樂觀鎖機制在一定程度上解決了資料庫效能開銷這個問題。它大多是基於資料版本( Version )記錄機制實現。
   可以使用版本號、時間戳等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,像資料庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。

   比較
   1、兩種鎖各有優缺點,不可認為一種好於另一種,像樂觀鎖適用於寫比較少的情況下,即衝突真的很少發生的時候,這樣可以省去了鎖的開銷,加大了系統的整個吞吐量。但如果經常產生衝突,上層應用會不斷的進行retry,這樣反倒是降低了效能,所以這種情況下用悲觀鎖就比較合適。
   2、悲觀鎖和樂觀鎖最大的區別是是否一直鎖定資源,悲觀鎖在事物的全流程鎖定資料,樂觀鎖不鎖定資料(用讀寫鎖是阻塞事物,而用樂觀鎖則會導致回滾,
這個是一種事物衝突後的不同鎖的表象)。

   3、悲觀鎖和樂觀鎖都是為了解決丟失更新問題或者是髒讀。悲觀鎖和樂觀鎖的重點就是是否在讀取記錄的時候直接上鎖。悲觀鎖的缺點很明顯,需要一個持續的資料庫連線,這在web應用中已經不適合了。

相關推薦

併發

      DRP學習中,我們對可能引起併發操作的情況使用了鎖,這次先理論上看看併發控制與鎖的一些內容吧。     併發控制     在多使用者環境中,在同一時間可能會有多個使用者更新相同的記錄,這會

Java的併發程式設計系列synchronized

private int count = 10; public void test(){ synchronized (this) { //任何執行緒要執行下面的程式碼,必須先拿到Demo02物件例項的鎖 count --;

執行緒同步

   im專案中都會存在離線訊息,我們在接受到訊息後,開啟子執行緒,處理相關業務邏輯。因為業務邏輯需遵循一定的處理順序,我們將部分程式碼加上了鎖。但是在離線訊息太多時,卻出現了執行緒問題:OutOfMemoryError: pthread_create (1040KB sta

Java併發程式設計和併發學習總結-大綱

系列 開篇語 想寫這樣一個東西很久了,在慕課網上學完某老師的課程(避免打廣告的嫌疑就不貼出來了,感興趣的同學可以去慕課網上去搜來看看,是個付費課程)之後就覺得應該有這樣的一個學習總結的東西來,後來因為懶又有其他事情耽誤了,然後又上了新專案(正好拿來練手了,當然

併發負載均衡——企業架構分析和DNS

最近研究了幾個關於阿里研究院對於高併發的解決方案,總結一下,漲漲姿勢。 企業級web專案架構圖   1、客戶端通過企業防火牆傳送請求 2、在App伺服器如tomcat接收客戶端請求前,面對高併發大資料量訪問的企業架構,會通過加入負載均衡主備伺服器將請求進行轉發到不

java併發實戰程式設計

總覽:什麼是鎖:鎖就是一種資源,用來進行共享資源的保護操作(也可以認為鎖是一條封鎖線,一個物件獲得了可以通過,否則就只能在隔離帶後面等待,除非輪到自己獲取到許可權)。 一.synchronized功能拓展:重入鎖 ReentrantLock     1.效能和synchr

精通併發 Netty 如何使用

精通併發與 Netty Netty 是一個非同步的,事件驅動的網路通訊框架,用於高效能的基於協議的客戶端和服務端的開發。 非同步指的是會立即返回,並不知道到底傳送過去沒有,成功沒有,一般都會使用監聽器來監聽返回。 事件驅動是指開發者只需要關注事件對應的回撥方法即可,比如 channel active,inac

聊聊併發實現幾種自旋

在聊聊高併發(五)理解快取一致性協議以及對併發程式設計的影響 我們瞭解了處理器快取一致性協議的原理,並且提到了它對併發程式設計的影響,“多個執行緒對同一個變數一直使用CAS操作,那麼會有大量修改操作,從而產生大量的快取一致性流量,因為每一次CAS操作都會發出廣播通知其他處理

JAVA併發 - 悲觀VS樂觀

文章目錄 悲觀鎖VS樂觀鎖 1.悲觀鎖 1.1什麼是悲觀鎖 1.2原始碼分析 synchronized Lock 1.3應用場景 1.4實現

第三章 處理機排程

3.1 處理機排程的層次和排程演算法的目標 1.系統執行並不一定存在高階排程 批處理系統有作業排程,分時系統和實時系統不需要作業排程。 2.引入中級排程的主要目的是,提高記憶體利用率和系統吞吐量,根據條件將一些程序調出或再調入記憶體。 3.排程程式也是程式。 4.排程原則

Java併發程式設計系列避免死

避免死鎖 (1)避免一個執行緒同時獲取多個鎖 (2)避免一個執行緒在鎖內佔用多個資源,儘量保證每個鎖只佔用一個資源 (3)使用定時鎖,使用lock.trylock(timeout)替代內部鎖機制 (4)

java多執行緒併發庫應用執行緒建立和定時任務Timer

1、建立執行緒的兩種方式, 通過start, 執行run方法。 第一種實現runnable, 定義類實現Runnable介面 重寫Runnable介面中的run方法 通過Thread建立執行緒物件 將Runnable介面的子類物件作為實際引數傳遞

C++併發程式設計2——為保護資料加

找到問題的解決辦法,而不是找蹩腳的介面。 在應屆生面試的時候,很多面試官都會問——“多執行緒如何共享資源”。在作業系統層面上可以給出若干關鍵詞答案,但是在語言層面,這個問題考慮的就沒有那麼簡單了。同時,很多人會將多執行緒資料共享和執行緒同步混淆。有關執行緒同步,我們

C++11 併發程式設計基礎併發、並行C++多執行緒

正文 C++11標準在標準庫中為多執行緒提供了元件,這意味著使用C++編寫與平臺無關的多執行緒程式成為可能,而C++程式的可移植性也得到了有力的保證。另外,併發程式設計可提高應用的效能,這對對效能錙銖必較的C++程式設計師來說是值得關注的。 回到頂部 1. 何為併發 併發指的是兩個或多個獨立的活動在同

利用JS 事件 Cnavas繪圖 以及 H5 快取寫的一個手勢解

之前參加360前端實習生 星計劃時,遇到一個任務,就是利用H5 localStorage實現密碼的存入和獲取。當時還沒有學canvas 繪圖,感覺利用原生JS和CSS實現比較複雜;這次剛好看了JS高程的Canvas繪圖,所以正好可以理論與實踐結合一下,試著做了一

德地圖心得—定位移動Maker處於地圖中心

摘要:從事android開發已有一年多,做了不少有關地圖開發的專案。遇到的坑也很多(官方demo畢竟只是參考,不一定是最簡潔的),下面就用程式碼展示我認為最簡潔的核心功能點,這也是我第一篇部落格,希望對你們能有些幫助! //地圖定位,使自定位Maker處於地圖中心

Tomcat--安裝部署

實現 get original servle body public -- ont str 一、Tomcat背景   自從JSP發布之後,推出了各式各樣的JSP引擎。Apache Group在完成GNUJSP1.0的開發以後,開始考慮在SUN的JSWDK基礎上開發一個可以

級控件

try message return ogre nis sta click down ble 1.Toast信息提示框b1.setOnClickListener(new OnClickListener() { @Override public void onC

Scala入門到精通——第二十二節 級類型

www 不同 out not cloneabl etag new 創建方式 技術分享 作者:搖擺少年夢 視頻地址:http://www.xuetuwuyou.com/course/12 本節主要內容 this.type使用 類型投影 結構類型

JVM中class文件探索解析

範圍 protected test except itl 指向 strac 相關 父類索引 一直想成為一名優秀的架構師的我,轉眼已經工作快兩年了,對於java內核了解甚少,閑來時間,看看JVM,吧自己的一些研究寫下來供大家參考,有不對的地方請指正。 廢話不多說,一起來看看J