在資料庫上實現類似鐵路售票鎖票功能

2021-09-06 14:45:31 字數 1845 閱讀 2195

要實現鐵路售票那樣的效果,如果有票查詢到就鎖定票,如果客人不購買再將票放回票池,這樣可以保證前來買票的旅客只要查詢到有票就一定能夠買到票。我們可以通過給資料庫增加乙個鎖定的標誌欄位來完成,但這裡我們可以試試資料庫本身的功能能否實現這個需求。

首先想到的是事務,如果對乙個表開始更新以後,那麼另外乙個會話查詢這個標的時候,會等待前乙個更新資料的會話釋放事務,這是因為普通的sql讀操作內部其實使用了「已提交讀」的事務隔離級別,可以保證資料的準確性。但是這不符合我們的需求,我們希望另外乙個查詢會話能夠很快的進行查詢,同時過濾掉被「鎖票」的資料。

在更新會話中,執行下面的查詢:

begin

tran

update users set name=

'aaa

'where uid=

610062

新開乙個查詢視窗,此時會新開乙個連線會話,執行乙個查詢:

select

*from localdb.dbo.users

此時發現查詢會話會一直等待,直到更新會話提交事務或者回滾事務:

begin

tran

update users set name=

'aaa

'where uid=

610062

rollback

再次執行上面的更新會話,但不提交事務,此時,我們的查詢會話可以使用 nolock,不會讓查詢等待。

select

*from localdb.dbo.users(nolock)

但是這樣把前面更新的資料也查詢出來了,不過是舊資料,不符合我們的需求。此時可以使用 行鎖加過濾鎖:

select

*from localdb.dbo.users with (rowlock,xlock,readpast)

成功實現需求!

另外,網友 聽風吹雨 也提供了另外的思路,詳細看下面的查詢**:

use

master

go--

-建立測試資料庫(快照)

create

database

snapshot_test

go--

-啟用資料行版本控制

alter

database snapshot_test set allow_snapshot_isolation on

gouse

snapshot_test

go--

1.建立測試表

create

table

tbreadlevel

(id

int,

name

nvarchar(20))

--2新增記錄

insert

tbreadlevel

select

1,'測試

'union

select

2,'快照測試'go

select id,name as

"修改前資料"

from

tbreadlevel

go--

3開啟事務

begin

tran

update

tbreadlevel

set name=

'jack_upd_快照

'where id=1--

5開啟另一條連線

settransaction

isolation

level

snapshot

select

*from tbreadlevel

資料庫鎖機制實現隔離

面對高併發加鎖可以從兩種層面來考慮 下面介紹 樂觀鎖 悲觀鎖 共享鎖s和排他鎖x 區別 1.樂觀鎖 從上面的例子可以看出,樂觀鎖機制避免了長事務中的資料庫加鎖開銷 操作員 a和操作員 b 操作過程中,都沒有對資料庫資料加鎖 大大提公升了大併發量下的系統整體效能表現。需要注意的是,樂觀鎖機制往往基於系...

2 DAS,NAS,SAN在資料庫儲存上的應用

一.硬碟介面型別 1.並行介面還是序列介面 1 並行介面,指的是並行傳輸的介面,比如有0 9十個數字,用10條傳輸線,那麼每根線只需要傳輸一位數字,即可完成。從理論上看,並行傳輸效率很高,但是由於線路上的物理原因,它的傳輸頻率不能太高,所以實際的傳輸速度並不和並行度成正比,甚至可能更差。2 序列介面...

windows上oracle資料庫檔案鎖定週期說明

大家應該注意到,windows系統中oracle資料庫在啟動後是不能刪除資料庫相關檔案的,這個特性可防止使用者像linux那樣不小心刪除了資料檔案。那具體oracle是在什麼時候鎖定檔案呢,下面詳細說明鎖定的細節。狀態 nomount 不鎖住任何檔案 狀態 mount 鎖住了控制檔案 狀態 open...