sql語句對資料庫表進行加鎖和解鎖

2022-05-08 08:18:11 字數 3643 閱讀 4376

鎖是資料庫中的乙個非常重要的概念,它主要用於多使用者環境下保證資料庫完整性和一致性。 我們知道,多個使用者能夠同時操縱同乙個資料庫中的資料,會發生資料不一致現象。即如果沒有鎖定且多個使用者同時訪問乙個資料庫,則當他們的事務同時使用相同的資料時可能會發生問題。這些問題包括:丟失更新、髒讀、不可重複讀和幻覺讀:

1.當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,會發生丟失更新問題。每個事務都不知道其它事務的存在。最後的更新將重寫由其它事務所做的更新,這將導致資料丟失。例如,兩個編輯人員製作了同一文件的電子複本。每個編輯人員獨立地更改其複本,然後儲存更改後的複本,這樣就覆蓋了原始文件。最後儲存其更改複本的編輯人員覆蓋了第乙個編輯人員所做的更改。如果在第乙個編輯人員完成之後第二個編輯人員才能進行更改,則可以避免該問題。

3.不可重複讀是指在乙個事務內,多次讀同一資料。在這個事務還沒有結束時,另外乙個事務也訪問該同一資料。那麼,在第乙個事務中的兩次讀資料之間,由於第二個事務的修改,那麼第乙個事務兩次讀到的的資料可能是不一樣的。這樣就發生了在乙個事務內兩次讀到的資料是不一樣的,因此稱為是不可重複讀。例如,乙個編輯人員兩次讀取同一文件,但在兩次讀取之間,作者重寫了該文件。當編輯人員第二次讀取文件時,文件已更改。原始讀取不可重複。如果只有在作者全部完成編寫後編輯人員才可以讀取文件,則可以避免該問題。

4.幻覺讀是指當事務不是獨立執行時發生的一種現象,例如第乙個事務對乙個表中的資料進行了修改,這種修改涉及到表中的全部資料行。同時,第二個事務也修改這個表中的資料,這種修改是向表中插入一行新資料。那麼,以後就會發生操作第乙個事務的使用者發現表中還有沒有修改的資料行,就好象發生了幻覺一樣。例如,乙個編輯人員更改作者提交的文件,但當生產部門將其更改內容合併到該文件的主複本時,發現作者已將未編輯的新材料新增到該文件中。如果在編輯人員和生產部門完成對原始文件的處理之前,任何人都不能將新材料新增到文件中,則可以避免該問題。

所以,處理多使用者併發訪問的方法是加鎖。鎖是防止其他事務訪問指定的資源控制、實現併發控制的一種主要手段。當乙個使用者鎖住資料庫中的某個物件時,其他使用者就不能再訪問該物件。加鎖對併發訪問的影響體現在鎖的粒度上。為了控制鎖定的資源,應該首先了解系統的空間管理。在sql server 2000系統中,最小的空間管理單位是頁,乙個頁有8k。所有的資料、日誌、索引都存放在頁上。另外,使用頁有乙個限制,這就是表中的一行資料必須在同乙個頁上,不能跨頁。頁上面的空間管理單位是盤區,乙個盤區是8個連續的頁。表和索引的最小占用單位是盤區。資料庫是由乙個或者多個表或者索引組成,即是由多個

sql語句:

lock tables tablename write;

lock tables tablename read;

insert into assignment values (1,7513,'0000-00-00',5),(1,7513,'2003-01-20',8.5);

unlock tables;

對於多個使用者同時提交表單,並且同時向資料庫中得到表單id,我是這樣解決的:

mysql_query("lock tables po read");

mysql_query("lock tables po write");

mysql_query("update po set id=id +1"));// increase po id

$sql = "select id from po";

$result = mysql_query($sql);

if ($row = mysql_fetch_assoc($result))

mysql_free_result($result);

mysql_query("unlock tables");

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

幫忙看看如何在這段**前後給資料庫寫加鎖和解鎖語句

'(在這裡給資料庫加鎖,如何寫加鎖語句?) 

...............

i = str(從記錄集rst0中得到最大入庫單號)

'若不加鎖,在這容易造成併發衝突。因為在申請到最大入庫單號之後還沒有來得及建立實際記錄,其它客戶端可能也申請到了同樣的入庫單號

..............

rst.open "select * from 入庫 where 入庫單號= " + i + " and 商品id=0 ", cn, adopenstatic, adlockoptimistic

if rst.recordcount = 0 then 下乙個入庫單號 = i + 1

...............

'(在這裡給資料庫解鎖,如何寫解鎖語句?)

解答1:先將需要加鎖執行的語句宣告成乙個事務(如2樓),然後加鎖,sql server中鎖的型別很多,看你需要加哪種型別的鎖: 

holdlock #將共享鎖保留到事務完成,而不是在相應的表、行或資料頁不再需要時就立即釋放鎖。holdlock 等同於 serializable。

nolock #不要發出共享鎖,並且不要提供排它鎖。當此選項生效時,可能會讀取未提交的事務或一組在讀取中間回滾的頁面。有可能發生髒讀。僅應用於 select 語句。

paglock #在通常使用單個表鎖的地方採用頁鎖。

readcommitted #用與執行在提交讀隔離級別的事務相同的鎖語義執行掃瞄。預設情況下,sql server 2000 在此隔離級別上操作。

readpast #跳過鎖定行。此選項導致事務跳過由其它事務鎖定的行(這些行平常會顯示在結果集內),而不是阻塞該事務,使其等待其它事務釋放在這些行上的鎖。 readpast 鎖提示僅適用於執行在提交讀隔離級別的事務,並且只在行級鎖之後讀取。僅適用於 select 語句。

readuncommitted #等同於 nolock。

repeatableread #用與執行在可重複讀隔離級別的事務相同的鎖語義執行掃瞄。

rowlock #使用行級鎖,而不使用粒度更粗的頁級鎖和表級鎖。

serializable #用與執行在可序列讀隔離級別的事務相同的鎖語義執行掃瞄。等同於 holdlock。

tablock #使用表鎖代替粒度更細的行級鎖或頁級鎖。在語句結束前,sql server 一直持有該鎖。但是,如果同時指定 holdlock,那麼在事務結束之前,鎖將被一直持有。

tablockx #使用表的排它鎖。該鎖可以防止其它事務讀取或更新表,並在語句或事務結束前一直持有。

updlock #讀取表時使用更新鎖,而不使用共享鎖,並將鎖一直保留到語句或事務的結束。updlock 的優點是允許您讀取資料(不阻塞其它事務)並在以後更新資料,同時確保自從上次讀取資料後資料沒有被更改。

xlock #使用排它鎖並一直保持到由語句處理的所有資料上的事務結束時。可以使用 paglock 或 tablock 指定該鎖,這種情況下排它鎖適用於適當級別的粒度。

解答2」要使一表在整個處理過程中不會被併發修改

可用事務

begin tran

select * from 表名 with holdlock

--處理語句

........

............

commit tran

加了 with holdlock後,在事務提交之前,別人動不了你的表

。。。。。。。。。。。。。。。。。。。。。。。。。。。。

對資料庫和表進行增刪改查

只是對資料庫和表的操作,並沒有操作表中的資料 1.c create 建立條件 語句建立資料庫 create database 資料庫名稱 建立資料庫,判斷不存在再建立 create database if not exists 資料庫名稱 建立資料庫,並指定字符集 create database 資...

使用sql進對資料庫表資料進行先分組後排序

在實際業務中,有一些場景需要對一組列表資料先分組後然後組內排序,這時不能單純的使用傳統的group by和order by語句了,因為會提示 x欄位必須在group by聚合函式中,為了解決此問題,我們可以使用row number over partition by 分組字段 order by 排序...

對資料庫進行操作

對資料庫進行操作 一 ddl 資料庫定義語言 對資料庫 表結構進行操作 建庫 建表 修改表結構 刪庫 刪表等等 sql語句大小寫不敏感 1.建立資料庫 2.顯示所有的資料庫 3.切換到要使用的資料庫,use 資料庫名稱 4.4.刪除資料庫 drop database if exists 資料庫名 5...