程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 也談SQL SERVER的鎖

也談SQL SERVER的鎖

編輯:關於SqlServer
常我們在進行數據庫的新增、修改、刪除、查詢的時候如果我們面對的不是多個用戶也及時單機處理的時候,
一般我們基本上不需要考慮數據庫的表鎖定以及死鎖之類情況,但是如果我們面對的是多用戶的並行處理的
網絡環境的時候我們對表鎖定的問題就需要較為仔細的分析和考慮,否則他給我們帶來的麻煩就不言而喻了,
下面就把我的在這件事情上遇到的問題以及解決辦法同大家一起分享。
也是在我的開發過程當中有這樣的事情:
兩個用戶同時保存新增的數據,我們的程序開始是這樣處理
cn.BeginTrans
cn.Execute "insert into tableA ....."
Set rs = cn.Execute("select count(*) from tableA where ...")
If rs.RecordCount > 0 Then
'表A 的字段A不能從復
cn.RollbackTrans
Else
cn.CommitTrans
End If

當SQL Server 在執行INSERT 命令時如果我們不添加任何參數時 數據庫默認申請一個 IX 鎖 給表A
這時候我們來分析上面的程序,當第一個用戶執行 cn.Execute "insert into tableA ....." Connection
向數據庫申請了一個 IX 鎖 給表A ,與此同時當第二個用戶執行 cn.Execute "insert into tableA ....." Connection 也向數據庫也成功地申請了一個 IX 鎖 給表A ,但是當執行
Set rs = cn.Execute("select count(*) from tableA where ...")
這一句的時候就會有問題產生,我們假設第一個用戶先一步執行 ,由於SELECT命令需要向數據庫申請一個
S 鎖給表A,但是由於這時候表A已經存在一個IX鎖並且屬於另外一個連接因此他只好在此等候。緊接著第二個
用戶也執行
Set rs = cn.Execute("select count(*) from tableA where ...")
他也會向數據庫申請一個S 鎖給表A ,這時候數據就會自動結束較晚申請IX鎖的連接同時回滾這個事務
這樣子對於我們的應用來說就是一個很大的失敗。

解決的辦法一,設置數據參數讓我們可以讀取沒有提交的數據、

cn.BeginTrans
cn.Execute "SET TRANSACTION ISOLATION LEVEL READ UNCOMM99vTED "
cn.Execute "insert into tableA ....."
Set rs = cn.Execute("select count(*) from tableA where ...")
If rs.RecordCount > 0 Then
'表A 的字段A不能從復
cn.RollbackTrans
Else
cn.CommitTrans
End If
cn.Execute "SET TRANSACTION ISOLATION LEVEL READ COMM99vTED "

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved