⑴ 如何處理資料庫並發問題
想要知道如何處理數據並發,自然需要先了解數據並發。
什麼是數據並發操作呢?
就是同一時間內,不同的線程同時對一條數據進行讀寫操作。
在互聯網時代,一個系統常常有很多人在使用,因此就可能出現高並發的現象,也就是不同的用戶同時對一條數據進行操作,如果沒有有效的處理,自然就會出現數據的異常。而最常見的一種數據並發的場景就是電商中的秒殺,成千上萬個用戶對在極端的時間內,搶購一個商品。針對這種場景,商品的庫存就是一個需要控制的數據,而多個用戶對在同一時間對庫存進行重寫,一個不小心就可能出現超賣的情況。
針對這種情況,我們如何有效的處理數據並發呢?
第一種方案、資料庫鎖
從鎖的基本屬性來說,可以分為兩種:一種是共享鎖(S),一種是排它鎖(X)。在MySQL的資料庫中,是有四種隔離級別的,會在讀寫的時候,自動的使用這兩種鎖,防止數據出現混亂。
這四種隔離級別分別是:
讀未提交(Read Uncommitted)
讀提交(Read Committed)
可重復讀(Repeated Read)
串列化(Serializable)
當然,不同的隔離級別,效率也是不同的,對於數據的一致性保證也就有不同的結果。而這些可能出現的又有哪些呢?
臟讀(dirty read)
當事務與事務之間沒有任何隔離的時候,就可能會出現臟讀。例如:商家想看看所有的訂單有哪些,這時,用戶A提交了一個訂單,但事務還沒提交,商家卻看到了這個訂單。而這時就會出現一種問題,當商家去操作這個訂單時,可能用戶A的訂單由於部分問題,導致數據回滾,事務沒有提交,這時商家的操作就會失去目標。
不可重復讀(unrepeatable read)
一個事務中,兩次讀操作出來的同一條數據值不同,就是不可重復讀。
例如:我們有一個事務A,需要去查詢一下商品庫存,然後做扣減,這時,事務B操作了這個商品,扣減了一部分庫存,當事務A再次去查詢商品庫存的時候,發現這一次的結果和上次不同了,這就是不可重復讀。
幻讀(phantom problem)
一個事務中,兩次讀操作出來的結果集不同,就是幻讀。
例如:一個事務A,去查詢現在已經支付的訂單有哪些,得到了一個結果集。這時,事務B新提交了一個訂單,當事務A再次去查詢時,就會出現,兩次得到的結果集不同的情況,也就是幻讀了。
那針對這些結果,不同的隔離級別可以干什麼呢?
「讀未提(Read Uncommitted)」能預防啥?啥都預防不了。
「讀提交(Read Committed)」能預防啥?使用「快照讀(Snapshot Read)」方式,避免「臟讀」,但是可能出現「不可重復讀」和「幻讀」。
「可重復讀(Repeated Red)」能預防啥?使用「快照讀(Snapshot Read)」方式,鎖住被讀取記錄,避免出現「臟讀」、「不可重復讀」,但是可能出現「幻讀」。
「串列化(Serializable)」能預防啥?有效避免「臟讀」、「不可重復讀」、「幻讀」,不過運行效率奇差。
好了,鎖說完了,但是,我們的資料庫鎖,並不能有效的解決並發的問題,只是盡可能保證數據的一致性,當並發量特別大時,資料庫還是容易扛不住。那解決數據並發的另一個手段就是,盡可能的提高處理的速度。
因為數據的IO要提升難度比較大,那麼通過其他的方式,對數據進行處理,減少資料庫的IO,就是提高並發能力的有效手段了。
最有效的一種方式就是:緩存
想要減少並發出現的概率,那麼讀寫的效率越高,讀寫的執行時間越短,自然數據並發的可能性就變小了,並發性能也有提高了。
還是用剛才的秒殺舉例,我們為的就是保證庫存的數據不出錯,賣出一個商品,減一個庫存,那麼,我們就可以將庫存放在內存中進行處理。這樣,就能夠保證庫存有序的及時扣減,並且不出現問題。這樣,我們的資料庫的寫操作也變少了,執行效率也就大大提高了。
當然,常用的分布式緩存方式有:Redis和Memcache,Redis可以持久化到硬碟,而Memcache不行,應該怎麼選擇,就看具體的使用場景了。
當然,緩存畢竟使用的范圍有限,很多的數據我們還是必須持久化到硬碟中,那我們就需要提高資料庫的IO能力,這樣避免一個線程執行時間太長,造成線程的阻塞。
那麼,讀寫分離就是另一種有效的方式了
當我們的寫成為了瓶頸的時候,讀寫分離就是一種可以選擇的方式了。
我們的讀庫就只需要執行讀,寫庫就只需要執行寫,把讀的壓力從主庫中分離出去,讓主庫的資源只是用來保證寫的效率,從而提高寫操作的性能。
⑵ 安卓中資料庫被鎖住是什麼意思
資料庫正常情況下是不會被鎖住的,除非有異常進程干擾。。。
⑶ sqlserver怎麼用sql查看具體那個表被鎖住了
詳細步驟如下:
1、點擊【新建查詢】按鈕,打開SQL命令編輯框,對資料庫表的操作以及維護都可以通過編輯SQL命令實現。
3、創建數據表的源代碼如下:
use test go
if exists(select name from sys.tables where name='Student')
drop table Student go
create table Student
(sname nchar(10) primary key,
sex nchar(2) not null,
bir datetime)
⑷ oracle資料庫的表什麼情況下會被鎖住
DML鎖又可以分為,行鎖、表鎖、死鎖
-行鎖:當事務執行資料庫插入、更新、刪除操作時,該事務自動獲得操作表中操作行的排它鎖。
-表級鎖:當事務獲得行鎖後,此事務也將自動獲得該行的表鎖(共享鎖),以防止其它事務進行DDL語句影響記錄行的更新。事務也可以在進行過程中獲得共享鎖或排它鎖,只有當事務顯示使用LOCK TABLE語句顯示的定義一個排它鎖時,事務才會獲得表上的排它鎖,也可使用LOCK TABLE顯示的定義一個表級的共享鎖(LOCK TABLE具體用法請參考相關文檔)。
-死鎖:當兩個事務需要一組有沖突的鎖,而不能將事務繼續下去的話,就出現死鎖。
如事務1在表A行記錄#3中有一排它鎖,並等待事務2在表A中記錄#4中排它鎖的釋放,而事務2在表A記錄行#4中有一排它鎖,並等待事務1在表A中記錄#3中排它鎖的釋放,事務1與事務2彼此等待,因此就造成了死鎖。死鎖一般是因拙劣的事務設計而產生。
死鎖只能使用SQL下:alter system kill session "sid,serial#";或者使用相關操作系統kill進程的命令,如UNIX下kill -9 sid,或者使用其它工具殺掉死鎖進程。
+DDL鎖又可以分為:排它DDL鎖、共享DDL鎖、分析鎖
-排它DDL鎖:創建、修改、刪除一個資料庫對象的DDL語句獲得操作對象的 排它鎖。如使用alter table語句時,為了維護數據的完成性、一致性、合法性,該事務獲得一排它DDL鎖。
-共享DDL鎖:需在資料庫對象之間建立相互依賴關系的DDL語句通常需共享獲得DDL鎖。
如創建一個包,該包中的過程與函數引用了不同的資料庫表,當編譯此包時,該事務就獲得了引用表的共享DDL鎖。
-分析鎖:ORACLE使用共享池存儲分析與優化過的SQL語句及PL/SQL程序,使運行相同語句的應用速度更快。一個在共享池中緩存的對象獲得它所引用資料庫對象的分析鎖。分析鎖是一種獨特的DDL鎖類型,ORACLE使用它追蹤共享池對象及它所引用資料庫對象之間的依賴關系。當一個事務修改或刪除了共享池持有分析鎖的資料庫對象時,ORACLE使共享池中的對象作廢,下次在引用這條SQL/PLSQL語句時,ORACLE重新分析編譯此語句。
⑸ Mysql資料庫全局鎖是如何引起的,如何解決
鎖產生的原因是因為請求某個資源而得不到滿足。
比如請求一需要資源順序為A - B -C
第二個請求需要的資源順序為B - A -C
當上面兩個請求同時進行時會有可能產生以下情況:請求一申請了資源A,請求二申請了資源B
然後請求一再去申請資源B時需要等待請求二完成,請求二去請求資源A時要等請求一完成。這樣請求一和請求二都在互相等待的時候就會一直都完不成就等於一個鎖鎖住了A、B資源誰也用不了了。
鎖差生的原因是:資料庫並發太高、程序設計不合理、資料庫操作處理時間太長。等
知道原理後可以針對性的優化資料庫和程序。
⑹ 用sql語句,怎麼解決mysql資料庫死鎖
MySQL死鎖問題的相關知識是本文我們主要要介紹的內容,接下來我們就來一一介紹這部分內容,希望能夠對您有所幫助。
1、MySQL常用存儲引擎的鎖機制
MyISAM和MEMORY採用表級鎖(table-level locking)
BDB採用頁面鎖(page-level locking)或表級鎖,默認為頁面鎖
InnoDB支持行級鎖(row-level locking)和表級鎖,默認為行級鎖
2、各種鎖特點
表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖沖突的概率最高,並發度最低
行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖沖突的概率最低,並發度也最高
頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,並發度一般
3、各種鎖的適用場景
表級鎖更適合於以查詢為主,只有少量按索引條件更新數據的應用,如Web應用
行級鎖則更適合於有大量按索引條件並發更新數據,同時又有並發查詢的應用,如一些在線事務處理系統
4、死鎖
是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。
表級鎖不會產生死鎖。所以解決死鎖主要還是針對於最常用的InnoDB。
5、死鎖舉例分析
在MySQL中,行級鎖並不是直接鎖記錄,而是鎖索引。索引分為主鍵索引和非主鍵索引兩種,如果一條sql語句操作了主鍵索引,MySQL就會鎖定這條主鍵索引;如果一條語句操作了非主鍵索引,MySQL會先鎖定該非主鍵索引,再鎖定相關的主鍵索引。
在UPDATE、DELETE操作時,MySQL不僅鎖定WHERE條件掃描過的所有索引記錄,而且會鎖定相鄰的鍵值,即所謂的next-key locking。
例如,一個表db。tab_test,結構如下:
id:主鍵;
state:狀態;
time:時間;
索引:idx_1(state,time)
出現死鎖日誌如下:
?***(1) TRANSACTION:
?TRANSACTION 0 677833455, ACTIVE 0 sec, process no 11393, OSthread id 278546 starting index read
?mysql tables in use 1, locked 1
?LOCK WAIT 3 lock struct(s), heap size 320
?MySQL thread id 83, query id 162348740 dcnet03 dcnet Searching rows for update
?update tab_test set state=1064,time=now() where state=1061 and time < date_sub(now(), INTERVAL 30 minute) (任務1的sql語句)
?***(1) WAITING FOR THIS LOCK TO BE GRANTED: (任務1等待的索引記錄)
?RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `db/tab_test` trx id 0 677833455 _mode X locks rec but not gap waiting
?Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
?0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 8616e642e706870; asc xxx.com/;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;
?*** (2) TRANSACTION:
?TRANSACTION 0 677833454, ACTIVE 0 sec, process no 11397, OS thread id 344086 updating or deleting, thread declared inside InnoDB 499
?mysql tables in use 1, locked 1
?3 lock struct(s), heap size 320, undo log entries 1
?MySQL thread id 84, query id 162348739 dcnet03 dcnet Updating update tab_test set state=1067,time=now () where id in (9921180) (任務2的sql語句)
?*** (2) HOLDS THE LOCK(S): (任務2已獲得的鎖)
?RECORD LOCKS space id 0 page no 849384 n bits 208 index `PRIMARY` of table `db/tab_test` trx id 0 677833454 lock_mode X locks rec but not gap
?Record lock, heap no 92 PHYSICAL RECORD: n_fields 11; compact format; info bits 0
?0: len 8; hex 800000000097629c; asc b ;; 1: len 6; hex 00002866eaee; asc (f ;; 2: len 7; hex 00000d40040110; asc @ ;; 3: len 8; hex 80000000000050b2; asc P ;; 4: len 8; hex 800000000000502a; asc P*;; 5: len 8; hex 8000000000005426; asc T&;; 6: len 8; hex 800012412c66d29c; asc A,f ;; 7: len 23; hex 8616e642e706870; asc uploadfire.com/hand.php;; 8: len 8; hex 800000000000042b; asc +;; 9: len 4; hex 474bfa2b; asc GK +;; 10: len 8; hex 8000000000004e24; asc N$;;
?*** (2) WAITING FOR THIS LOCK TO BE GRANTED: (任務2等待的鎖)
?RECORD LOCKS space id 0 page no 843102 n bits 600 index `idx_1` of table `db/tab_test` trx id 0 677833454 lock_mode X locks rec but not gap waiting
?Record lock, heap no 395 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
?0: len 8; hex 8000000000000425; asc %;; 1: len 8; hex 800012412c66d29c; asc A,f ;; 2: len 8; hex 800000000097629c; asc b ;;
?*** WE ROLL BACK TRANSACTION (1)
?(回滾了任務1,以解除死鎖)
原因分析:
當「update tab_test set state=1064,time=now() where state=1061 and time < date_sub(now(), INTERVAL 30 minute)」執行時,MySQL會使用idx_1索引,因此首先鎖定相關的索引記錄,因為idx_1是非主鍵索引,為執行該語句,MySQL還會鎖定主鍵索引。
假設「update tab_test set state=1067,time=now () where id in (9921180)」幾乎同時執行時,本語句首先鎖定主鍵索引,由於需要更新state的值,所以還需要鎖定idx_1的某些索引記錄。
這樣第一條語句鎖定了idx_1的記錄,等待主鍵索引,而第二條語句則鎖定了主鍵索引記錄,而等待idx_1的記錄,這樣死鎖就產生了。
6、解決辦法
拆分第一條sql,先查出符合條件的主鍵值,再按照主鍵更新記錄:
?select id from tab_test where state=1061 and time < date_sub(now(), INTERVAL 30 minute);
?update tab_test state=1064,time=now() where id in(......);
⑺ sqlite查詢過快導致資料庫鎖住
sqlite查詢過快導致資料庫鎖住
原因:更新寫的時候需要排他鎖。但是查詢語句有些東西沒有正常釋放,導致共享鎖一直未正常釋放,排他鎖得不到滿足。幾經測試,終於發現,是ExecuteReader這個函數在作怪,這個函數返回的是一個SQLiteDataReader對象,如果使用的時候和上面的代碼一樣只是read就完了,沒有去關閉,這個共享鎖仍舊存在。
解決方案:
執行完畢釋放一下即可。
⑻ 帆軟配置資料庫被鎖住
帆軟配置資料庫被鎖住:需要自增主鍵智能資料庫設置自增 , 帆軟報表 目前只能設置隨機字元串,無法設置自增,如果只是在頁面顯示的話可以用seq ( ) 方法
⑼ 求助,資料庫表有一個鎖住了無法編輯怎麼弄
在使用Excel 時有時會希望把某些單元格鎖定,這樣的不會造成誤刪、誤改某些數據。原先就聽說可以把某些單元格設置成「只讀」的,如何鎖定單元格,讓單元格數據不能修改呢? 我們看一下下面這個例子,「總合」這一欄是計算所得的,所以這一列上的數據都不需要直接輸入或修改。我們可以把這一列鎖起來: 先選定任意一個單元格,點右鍵,選設置單元格格式。 點開保護選項卡,我們會發現這里的鎖定默認情況下就選中了。也就是說在默認情況下,一旦鎖定了工作表,所有的單元格就鎖定了。 所以,我們選中所有的單元格(Ctrl+A),點右鍵,選設置單元格格式。然後在保護選項卡上把鎖定勾去掉。 然後選中需要保護的單元格,在這個例子中是整個「總合」這一列(因為這一列是自動計算出來的),把它的鎖定勾上。 提示:為方便起見,你也可以只把需要編輯的那部分單元格的鎖定取消掉。 在我們設好了哪些單元格需要鎖定後,現在我們可以把鎖定功能打開了。 點開審閱選項卡,點保護工作簿。 在允許此工作表的所有用戶進行下面,可以選用戶可以做哪些操作。一般留著默認選項即可,然後按確定。 註:如果在這里設置了密碼,以後解開鎖定時就要輸入密碼。密碼一般可以不設。 我們嘗試編輯「總合」一欄中的數據,會彈出一個消息說不能編輯內容。 雖然這個單元格鎖定了,但是並不影響它數據更新。比方說,這個是「總合」欄,我們把單獨數據(源數據)改了,總合還是會自動計算的。 如果需要解除鎖定,在審閱選項卡上點撤銷工作表保護