好的,謝謝,我叫王業鑫,來自於河南,於2010年畢業於河南理工,目前從事.Net開發已經有差很少五年工做經驗了。個人第一家就任公司叫Edoc2,主要是爲企業作OA文檔管理系統和工做流,前兩年我在項目部,主要職責是項目開發,我所作的主要項目是上海百視通,新城股,浙江台州聯化科技,上海電纜研究所,這些項目都取得了成功,而且目前和公司還保持這合做關係,爲公司帶來了長久的經濟利益,其中這裏面有三個項目是我核心參與或帶領團隊負責去開發的,由於常常和客戶,實施顧問,項目經理等一塊兒商討需求即計劃的制定即排期,讓我在帶領團隊方面積累了一些經驗。後期基於我的對技術的興趣,就和公司領導層商討,最終決定讓我進研發部,從事產品研發的相關工做。在研發部這段期間,我作了兩個產品,分別是ISO文控管理系統,PDMS項目管理系統…javascript
多線程css
頁的生命週期html
頁請求:編譯頁前端
開始:設置頁的Response Requestjava
頁初始化:web
加載:面試
驗證:算法
回發事件處理:sql
呈現數據庫
卸載
理解MVC原理,理解MVC的一些使用技巧
asp.net Web Form MVC 區別
.net 運行原理
Iis怎麼運行asp.net
GC內存回收 標記壓縮算法 分代算法 cmd.Dispose();
類,抽象類,藉口區別
類繼承類
可實現多態
抽象類
1> 抽象類中能夠定義字段,並賦值
2> 抽象類中能夠定義屬性
3> 抽象類中能夠包含非抽象方法
4> 抽象類中能夠包含抽象方法,但繼承是必須事項抽象類中的全部抽象方法,不然編譯不經過。
5> 抽象類不能實例化,抽象類不能用sealed來修飾
6> 抽象類中能夠有需方法(virtual),子類集成抽象類仍是用override 重寫該方法
7> 子類集成抽象類後,實現抽象方法用override
8> 子類具備和基類相同的方法,能夠(建議)加個new,隱藏基類成員,可是不是強制行要加,調用基類成員用base
多態
設計模式
狀態模式 容許一個對象在其內部狀態改變時改變他的行爲,好像是修改子類。
策略模式 實現統一接口,子類不一樣;
觀察者模式 委託事件的實現
簡單工廠模式
抽象工廠模式
單例工廠模式 對象僅有一個實例,再就是提供一全局訪問點。
適配器模式,裝飾着模式 都是對藉口的在封裝
原型模式 對象的拷貝
單一性原則,開放封閉原則,里氏替換原則,依賴倒置,藉口隔離原則,最少知識原則,合成複用原則;
地址:http://www.cnblogs.com/yexinw/p/4115498.html
開發過程當中使用好的規範
經常使用IOC框架彙總及性能總結
拷貝操做(深拷貝和淺拷貝)
委託事件原理及用途
前端
服務端
數據庫
Ajax
ansych
指數表示法 var test = 2e3; //2*10*10*10
轉義字符 var test = 'aa\nbb';
流程設計 有點相似於viso流程圖,
組織架構
流程日誌監控
.Net 運行過程
代碼編譯成DLL==》編譯的DLL爲中間語言MSIL==》MSIL運行在 .Net Framework 上下文中;
www.educity.cn 發佈者:cszw12302 來源:網絡轉載 發佈日期:2013年10月28日 文章評論 發表文章
SP.NET是一個很是強大的構建Web應用的平臺,它提供了極大的靈活性和能力以至於能夠用它來構建全部類型的Web應用。
絕大多數的人只熟悉高層的框架如: WebForms 和 WebServices --這些都在ASP.NET層次結構在最高層。
這篇文章的資料收集整理自各類微軟公開的文檔,經過比較 IIS五、IIS六、IIS7 這三代 IIS 對請求的處理過程, 讓咱們熟悉 ASP.NET的底層機制 並對請求(request)是怎麼從Web服務器傳送到ASP.NET運行時有所瞭解。經過對底層機制的瞭解,可讓咱們對 有更深的理解。
IIS 5 的 請求處理過程
|
IIS 5的請求處理過程 |
對圖的解釋:
IIS 5.x 一個顯著的特徵就是 Web Server 和真正的 ASP.NET Application 的分離。做爲 Web Server 的IIS運行在一個名爲 InetInfo.exe 的進程上,InetInfo.exe 是一個Native Executive,並非一個託管的程序,而咱們真正的 ASP.NET Application 則是運行在一個叫作 aspnet_wp 的 Worker Process 上面,在該進程初始化的時候會加載CLR,因此這是一個託管的環境。
ISAPI: 指可以處理各類後綴名的應用程序。 ISAPI 是下面單詞的簡寫 :Internet Server Application Programe Interface,互聯網服務器應用程序接口。
IIS 5 模式的特色:
一、首先,同一臺主機上在同一時間只能運行一個 aspnet_wp 進程,每一個基於虛擬目錄的 ASP.NET Application 對應一個 Application Domain ,也就是說每一個 Application 都運行在同一個 Worker Process 中,Application之間的隔離是基於 Application Domain 的,而不是基於Process的。
二、其 次,ASP.NET ISAPI 不但負責建立 aspnet_wp Worker Process,並且負責監控該進程,若是檢測到 aspnet_wp 的 Performance 下降到某個設定的下限,ASP.NET ISAPI 會負責結束掉該進程。當 aspnet_wp 結束掉以後,後續的 Request 會致使ASP.NET ISAPI 從新建立新的 aspnet_wp Worker Process.
三、最後,因爲 IIS 和 Application 運行在他們各自的進程中,他們之間的通訊必須採用特定的通訊機制。本質上 IIS 所在的 InetInfo 進程和 Worker Process 之間的通訊是同一臺機器不一樣進程的通訊(local interprocess communications),處於Performance的考慮,他們之間採用基於Named pipe的通訊機制。ASP.NET ISAPI和Worker Process之間的通訊經過他們之間的一組Pipe實現。一樣處於Performance的緣由,ASP.NET ISAPI 經過異步的方式將Request 傳到Worker Process 並得到 Response,可是 Worker Process 則是經過同步的方式向 ASP.NET ISAPI 得到一些基於 Server 的變量。
IIS6 的 請求處理過程
|
IIS6 的 請求處理過程 |
對圖的解釋:
IIS 5.x 是經過 InetInfo.exe 監聽 Request 並把Request分發到Work Process.換句話說,在IIS 5.x中對Request的監聽和分發是在User Mode中進行,在IIS 6中,這種工做被移植到kernel Mode中進行,全部的這一切都是經過一個新的組件:http.sys 來負責。
注:爲了避 免用戶應用程序訪問或者修改關鍵的操做系統數據,windows提供了兩種處理器訪問模式:用戶模式(User Mode)和內核模式(Kernel Mode)。通常地,用戶程序運行在User mode下,而操做系統代碼運行在Kernel Mode下。Kernel Mode的代碼容許訪問全部系統內存和全部CPU指令。
在User Mode下,http.sys接收到一個基於 aspx 的http request,而後它會根據IIS中的 Metabase 查看該基於該 Request 的 Application 屬於哪一個Application Pool, 若是該Application Pool不存在,則建立之。不然直接將 request 發到對應Application Pool 的 Queue中。
每一個 Application Pool 對應着一個Worker Process:w3wp.exe,毫無疑問他是運行在User Mode下的。在IIS Metabase 中維護着 Application Pool 和worker process的Mapping.WAS(Web Administrative service)根據這樣一個mapping,將存在於某個Application Pool Queue的request 傳遞到對應的worker process(若是沒有,就建立這樣一個進程)。在 worker process 初始化的時候,加載ASP.NET ISAPI,ASP.NET ISAPI 進而加載CLR.最後的流程就和IIS 5.x同樣了:經過AppManagerAppDomainFactory 的 Create方法爲 Application 建立一個Application Domain;經過 ISAPIRuntime 的 ProcessRequest處理Request,進而將流程進入到ASP.NET Http Runtime Pipeline.
IIS 7 的 請求處理過程
IIS7 站點啓動並處理請求的步驟以下圖:
步驟 1 到 6 ,是處理應用啓動,啓動好後,之後就不須要再走這個步驟了。
|
IIS 7 的 請求處理過程 |
上圖的8個步驟分別以下:
一、當客戶端瀏覽器開始HTTP 請求一個WEB 服務器的資源時,HTTP.sys 攔截到這個請求。
二、HTTP.sys contacts WAS to obtain information from the configuration store.
三、WAS 向配置存儲中心請求配置信息。nfig。
四、WWW 服務接受到配置信息,配置信息指相似應用程序池配置信息,站點配置信息等等。
五、WWW 服務使用配置信息去配置 HTTP.sys 處理策略。
六、WAS starts a worker process for the application pool to which the request was made.
七、The worker process processes the request and returns a response to HTTP.sys.
八、客戶端接受處處理結果信息。
W3WP.exe 進程中又是若是處理得呢?? IIS 7 的應用程序池的託管管道模式分兩種: 經典和集成。 這兩種模式下處理策略各不相通。
IIS 6 以及 IIS7 經典模式的託管管道的架構
在IIS7以前,ASP.NET 是以 IIS ISAPI extension 的方式外加到 IIS,其實包括 ASP 以及 PHP,也都以相同的方式配置(PHP 在 IIS 採用了兩種配置方式,除了 IIS ISAPI extension 的方式,也包括了 CGI 的方式,系統管理者能選擇 PHP 程序的執行方式),所以客戶端對 IIS 的 HTTP 請求會先經由 IIS 處理,而後 IIS 根據要求的內容類型,若是是 HTML 靜態網頁就由 IIS 自行處理,若是不是,就根據要求的內容類型,分派給各自的 IIS ISAPI extension;若是要求的內容類型是 ASP.NET,就分派給負責處理 ASP.NET 的 IIS ISAPI extension,也就是 aspnet_isapi.dll。下圖是這個架構的示意圖。
|
IIS6 的執行架構圖,以及IIS7應用程序池配置成經典模式的執行架構圖 |
IIS7 應用程序池的 託管管道模式 經典 模式也是這樣的工做原理。 這種模式是兼容IIS 6 的方式, 以減小升級的成本。
IIS 7 應用程序池的 託管管道模式 集成模式
|
IIS 7 的執行架構圖(集成託管信道模式下的架構) |
小結
IIS5 到 IIS6 的改進,主要是 HTTP.sys 的改進。
IIS6 到 IIS7 的改進,主要是 ISAPI 的改進。
請求不一樣
WebForm
頁面是繼承了IHttpHandler的一個類,最後執行ProcessRequest()方法
WebForm沒法把客戶端編程和服務端編程混在一塊兒,沒法精確控制頁面的元素,可是在.net 中獲得了改善。
用webform,就須要大量的去維護控件的viewstate,和生命週期
所以 ASP.NET 將不會對 .htm 文件請求執行身份驗證或受權檢查,但IIS 集成模式是能夠的;
Asp.Net MVC
問題1:什麼是HttpHandler?
問題2:什麼是HttpModule?
問題3:何時應該使用HttpHandler何時使用HttpModule?
答案1:HttpHandler,Http請求的處理者,例如ScriptHandler、WebServiceHandler,IHttpHandler的實現都是爲了處理某一類的請求。如ScriptHandler負責處理對腳本的請求。
答案2:HttpModule,Http模塊。實際上就是那19個標準事件的處理者,或者說19個標準事件的訂閱者,好比OutputCacheModule,SessionStateModule。詳細能夠到在這篇文章裏面看到http://www.cnblogs.com/kissdodog/p/3527922.html。
一、因爲HTTP請求有不少種請求類型,好比請求aspx、html、jpg等等。所以,僅僅由HttpApplication直接處理請求時 很臃腫的,並且不利於擴展。所以Asp.net採用了抽象工廠模式來處理這些請求。Asp.net在web.config的架構中,容許咱們制定某些請求 映射到一個HttpHandlerFactory。
<!--適用於IIS6的配置-->
<system.web>
<httpHandlers>
<add path="*.aspx" verb="*" type="MyMVC.MvcPageHandlerFactory, MyMVC" validate="true" />
</httpHandlers>
</system.web>
<!--適用於IIS7的配置(集成模式)-->
<system.webServer>
<handlers>
<add name="MvcPageHandlerFactory" verb="*" path="*.aspx" type="MyMVC.MvcPageHandlerFactory, MyMVC" preCondition="integratedMode" />
</handlers>
</system.webServer>
因此,咱們應該這樣理解HttpHanlder:一個HttpHanlder用於響應一類的請求,爲一類的請求生成響應結果。
咱們常常用到的HttpHanlder有哪些?
1. aspx頁面。
2. asmx服務文件。
3. ashx文件(通常處理程序)。
4. 實現IHttpHandler接口的自定義類型。
咱們一般使用HttpHanlder作什麼?
HttpHanlder類型 |
實現目標 |
aspx頁面 |
響應aspx的請求,輸出HTML結果 |
asmx服務文件 |
響應服務調用 |
ashx文件(通常處理程序) |
實現簡單的AJAX響應 |
實現IHttpHandler接口的自定義類 |
響應什麼擴展名的請求? |
有時候有些頁面須要一些相同的檢查功能,好比身份驗證。明顯使用HttpHandler是不方便的,由於不是全部的頁面都須要去調用那些相同的功能。
HttpModule 的設計正是提供了一個靈活的方法解決這種功能重用的問題,它採用事件(觀察者)的設計模式,將某些HttpHandler都須要的功能抽取出來,造成不一樣 的觀察者類型,這些觀察者類型能夠編譯成類庫形式,供多個網站共用。爲了讓ASP.NET管線更靈活,ASP.NET容許咱們再web.config中自 由配置須要的HttpModule。
<!--適用於IIS6的配置-->
<system.web>
<httpModules>
<add name="SetOutputCacheModule" type="MyMVC.SetOutputCacheModule, MyMVC"/>
</httpModules>
</system.web>
<!--適用於IIS7的配置(集成模式)-->
<system.webServer>
<modules>
<add name="SetOutputCacheModule" type="MyMVC.SetOutputCacheModule, MyMVC" preCondition="integratedMode" />
</modules>
</system.webServer>
配置只是告訴ASP.NET,這些HttpModule須要運行起來,可能會用得着。
咱們用HttpModule作什麼事情?
1. 修改某些請求(例如前面的示例修改了響應頭)。
2. 檢查檢查請求(例如身份認證檢查)。
HttpModule能處理哪些請求呢?
1. 默認是所有進入ASP.NET的請求。
2. 若是隻須要處理部分請求,那麼請自行判斷。
HttpHandler至關於一條水管,HttpModule至關於一小節水管。HttpHandler有不少條,一條流油,一條流水等等。HttpModule至關於一小截,須要過濾的長水管裏面均可以裝上。
SQL Server中解決死鎖的新方法介紹
數據庫操做的死鎖是不可避免的,本文並不打算討論死鎖如何產生,重點在於解決死鎖,經過SQL Server 2005, 如今彷佛有了一種新的解決辦法。
將下面的SQL語句放在兩個不一樣的鏈接裏面,而且在5秒內同時執行,將會發生死鎖。
use Northwindbegin tran insert into Orders(CustomerId) values(@#ALFKI@#) waitfor delay @#00:00:05@# select * from Orders where CustomerId = @#ALFKI@#commitprint @#end tran@# |
SQL Server對付死鎖的辦法是犧牲掉其中的一個,拋出異常,而且回滾事務。在SQL Server 2000,語句一旦發生異常,T-SQL將不會繼續運行,上面被犧牲的鏈接中, print @#end tran@#語句將不會被運行,因此咱們很難在SQL Server 2000的T-SQL中對死鎖進行進一步的處理。
如今不一樣了,SQL Server 2005能夠在T-SQL中對異常進行捕獲,這樣就給咱們提供了一條處理死鎖的途徑:
下面利用的try ... catch來解決死鎖。
SET XACT_ABORT ONdeclare @r intset @r = 1while @r <= 3begin begin tran begin try insert into Orders(CustomerId) values(@#ALFKI@#) waitfor delay @#00:00:05@# select * from Orders where CustomerId = @#ALFKI@# commit break end try begin catch rollback waitfor delay @#00:00:03@# set @r = @r + 1 continue end catchend |
解決方法固然就是重試,但捕獲錯誤是前提。rollback後面的waitfor不可少,發生衝突後須要等待一段時間,@retry數目能夠調整以應付不一樣的要求。
可是如今又面臨一個新的問題: 錯誤被掩蓋了,一但問題發生而且超過3次,異常卻不會被拋出。SQL Server 2005 有一個RaiseError語句,能夠拋出異常,但卻不能直接拋出原來的異常,因此須要從新定義發生的錯誤,如今,解決方案變成了這樣:
declare @r intset @r = 1while @r <= 3begin begin tran begin try insert into Orders(CustomerId) values(@#ALFKI@#) waitfor delay @#00:00:05@# select * from Orders where CustomerId = @#ALFKI@# commit break end try begin catch rollback waitfor delay @#00:00:03@# set @r = @r + 1 continue end catchendif ERROR_NUMBER() <> 0begin declare @ErrorMessage nvarchar(4000); declare @ErrorSeverity int; declare @ErrorState int; select @ErrorMessage = ERROR_MESSAGE(), @ErrorSeverity = ERROR_SEVERITY(), @ErrorState = ERROR_STATE(); raiserror (@ErrorMessage, @ErrorSeverity, @ErrorState );end |
我但願未來SQL Server 2005可以直接拋出原有異常,好比提供一個無參數的RaiseError。
所以方案有點臃腫,但將死鎖問題封裝到T-SQL中有助於明確職責,提升高層系統的清晰度。如今,對於DataAccess的代碼,或許不再須要考慮死鎖問題了
========================================================================
SQL Server2000中死鎖經驗總結
雖然不能徹底避免死鎖,但可使死鎖的數量減至最少。將死鎖減至最少能夠增長事務的吞吐量並減小系統開銷,由於只有不多的事務:
下列方法有助於最大限度地下降死鎖:
按同一順序訪問對象
若是全部併發事務按同一順序訪問對象,則發生死鎖的可能性會下降。例如,若是兩個併發事務得到 Supplier 表上的鎖,而後得到 Part 表上的鎖,則在其中一個事務完成以前,另外一個事務被阻塞在 Supplier 表上。第一個事務提交或回滾後,第二個事務繼續進行。不發生死鎖。將存儲過程用於全部的數據修改能夠標準化訪問對象的順序。
避免事務中的用戶交互
避 免編寫包含用戶交互的事務,由於運行沒有用戶交互的批處理的速度要遠遠快於用戶手動響應查詢的速度,例如答覆應用程序請求參數的提示。例如,若是事務正在 等待用戶輸入,而用戶去吃午飯了或者甚至回家過週末了,則用戶將此事務掛起使之不能完成。這樣將下降系統的吞吐量,由於事務持有的任何鎖只有在事務提交或 回滾時纔會釋放。即便不出現死鎖的狀況,訪問同一資源的其它事務也會被阻塞,等待該事務完成。
保持事務簡短並在一個批處理中
在同一數據庫中併發執行多個須要長時間運行的事務時一般發生死鎖。事務運行時間越長,其持有排它鎖或更新鎖的時間也就越長,從而堵塞了其它活動並可能致使死鎖。
保持事務在一個批處理中,能夠最小化事務的網絡通訊往返量,減小完成事務可能的延遲並釋放鎖。
使用低隔離級別
肯定事務是否能在更低的隔離級別上運行。執行提交讀容許事務讀取另外一個事務已讀取(未修改)的數據,而沒必要等待第一個事務完成。使用較低的隔離級別(例如提交讀)而不使用較高的隔離級別(例如可串行讀)能夠縮短持有共享鎖的時間,從而下降了鎖定爭奪。
使用綁定鏈接
使用綁定鏈接使同一應用程序所打開的兩個或多個鏈接能夠相互合做。次級鏈接所得到的任何鎖能夠象由主鏈接得到的鎖那樣持有,反之亦然,所以不會相互阻塞
檢測死鎖
若是發生死鎖了,咱們怎麼去檢測具體發生死鎖的是哪條SQL語句或存儲過程?
這時咱們可使用如下存儲過程來檢測,就能夠查出引發死鎖的進程和SQL語句。SQL Server自帶的系統存儲過程sp_who和sp_lock也能夠用來查找阻塞和死鎖, 但沒有這裏介紹的方法好用。
use master
go
create procedure sp_who_lock
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry int,
@intRowcount int,
@intCountProperties int,
@intCounter int
create table #tmp_lock_who (
id int identity(1,1),
spid smallint,
bl smallint)
IF @@ERROR<>0 RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select 0 ,blocked
from (select * from sysprocesses where blocked>0 ) a
where not exists(select * from (select * from sysprocesses where blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where blocked>0
IF @@ERROR<>0 RETURN @@ERROR
-- 找到臨時表的記錄數
select @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if @intCountProperties=0
select '如今沒有阻塞和死鎖信息' as message
-- 循環開始
while @intCounter <= @intCountProperties
begin
-- 取第一條記錄
select @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
select '引發數據庫死鎖的是: '+ CAST(@bl AS VARCHAR(10)) + '進程號,其執行的SQL語法以下'
else
select '進程號SPID:'+ CAST(@spid AS VARCHAR(10))+ '被' + '進程號SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其當前進程執行的SQL語法以下'
DBCC INPUTBUFFER (@bl )
end
-- 循環指針下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end
殺死鎖和進程
如何去手動的殺死進程和鎖?最簡單的辦法,從新啓動服務。可是這裏要介紹一個存儲過程,經過顯式的調用,能夠殺死進程和鎖。
use master
go
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[p_killspid]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[p_killspid]
GO
create proc p_killspid
@dbname varchar(200) --要關閉進程的數據庫名
as
declare @sql nvarchar(500)
declare @spid nvarchar(20)
declare #tb cursor for
select spid=cast(spid as varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)
open #tb
fetch next from #tb into @spid
while @@fetch_status=0
begin
exec('kill '+@spid)
fetch next from #tb into @spid
end
close #tb
deallocate #tb
go
--用法
exec p_killspid 'newdbpy'
查看鎖信息
如何查看系統中全部鎖的詳細信息?在企業管理管理器中,咱們能夠看到一些進程和鎖的信息,這裏介紹另一種方法。
--查看鎖信息
create table #t(req_spid int,obj_name sysname)
declare @s nvarchar(4000)
,@rid int,@dbname sysname,@id int,@objname sysname
declare tb cursor for
select distinct req_spid,dbname=db_name(rsc_dbid),rsc_objid
from master..syslockinfo where rsc_type in(4,5)
open tb
fetch next from tb into @rid,@dbname,@id
while @@fetch_status=0
begin
set @s='select @objname=name from ['+@dbname+']..sysobjects where id=@id'
exec sp_executesql @s,N'@objname sysname out,@id int',@objname out,@id
insert into #t values(@rid,@objname)
fetch next from tb into @rid,@dbname,@id
end
close tb
deallocate tb
select 進程id=a.req_spid
,數據庫=db_name(rsc_dbid)
,類型=case rsc_type when 1 then 'NULL 資源(未使用)'
when 2 then '數據庫'
when 3 then '文件'
when 4 then '索引'
when 5 then '表'
when 6 then '頁'
when 7 then '鍵'
when 8 then '擴展盤區'
when 9 then 'RID(行 ID)'
when 10 then '應用程序'
end
,對象id=rsc_objid
,對象名=b.obj_name
,rsc_indid
from master..syslockinfo a left join #t b on a.req_spid=b.req_spid
go
drop table #t
總結
雖然不能徹底避免死鎖,但咱們能夠將死鎖減至最少,並經過必定的方法來檢測死鎖。
-------------------------------------------------------------------------------------------------
SQL Server死鎖的分析
SQL Server數據庫發生死鎖時不會像ORACLE那樣自動生成一個跟蹤文件。有時能夠在[管理]->[當前活動] 裏看到阻塞信息(有時SQL Server企業管理器會由於鎖太多而沒有響應).
設定跟蹤1204:
USE MASTER
DBCC TRACEON (1204,-1)
顯示當前啓用的全部跟蹤標記的狀態:
DBCC TRACESTATUS(-1)
取消跟蹤1204:
DBCC TRACEOFF (1204,-1)
在設定跟蹤1204後,會在數據庫的日誌文件裏顯示SQL Server數據庫死鎖時一些信息。但那些信息很難看懂,須要對照SQL Server聯機叢書仔細來看。根據PAG鎖要找到相關數據庫表的方法:
DBCC TRACEON (3604)
DBCC PAGE (db_id,file_id,page_no)
DBCC TRACEOFF (3604)
請參考sqlservercentral.com上更詳細的講解.但又從CSDN學到了一個找到死鎖緣由的方法。我稍加修改, 去掉了遊標操做並增長了一些提示信息,寫了一個系統存儲過程sp_who_lock.sql。代碼以下:
if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[sp_who_lock]')
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_who_lock]
GO
/********************************************************
// 學習到並改寫
// 說明 : 查看數據庫裏阻塞和死鎖狀況
********************************************************/
use master
go
create procedure sp_who_lock
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry int,
@intRowcount int,
@intCountProperties int,
@intCounter int
create table #tmp_lock_who (
id int identity(1,1),
spid smallint,
bl smallint)
IF @@ERROR<>0 RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select 0 ,blocked
from (select * from sysprocesses where blocked>0 ) a
where not exists(select * from (select * from sysprocesses
where blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where blocked>0
IF @@ERROR<>0 RETURN @@ERROR
-- 找到臨時表的記錄數
select @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if @intCountProperties=0
select '如今沒有阻塞和死鎖信息' as message
-- 循環開始
while @intCounter <= @intCountProperties
begin
-- 取第一條記錄
select @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
select '引發數據庫死鎖的是: '+ CAST(@bl AS VARCHAR(10))
+ '進程號,其執行的SQL語法以下'
else
select '進程號SPID:'+ CAST(@spid AS VARCHAR(10))+ '被'
+ '進程號SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其當前進程執行的SQL語法以下'
DBCC INPUTBUFFER (@bl )
end
-- 循環指針下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end
須要的時候直接調用:
sp_who_lock
就能夠查出引發死鎖的進程和SQL語句.
SQL Server自帶的系統存儲過程sp_who和sp_lock也能夠用來查找阻塞和死鎖, 但沒有這裏介紹的方法好用。若是想知道其它tracenum參數的含義,請看http://www.sqlservercentral.com/文章
咱們還能夠設置鎖的超時時間(單位是毫秒), 來縮短死鎖可能影響的時間範圍:
例如:
use master
seelct @@lock_timeout
set lock_timeout 900000
-- 15分鐘
seelct @@lock_timeout
其實全部的死鎖最深層的緣由就是一個:資源競爭
表現一:
一個用戶A 訪問表A(鎖住了表A),而後又訪問表B
另外一個用戶B 訪問表B(鎖住了表B),而後企圖訪問表A
這時用戶A因爲用戶B已經鎖住表B,它必須等待用戶B釋放表B,才能繼續,好了他老人家就只好老老實實在這等了
一樣用戶B要等用戶A釋放表A才能繼續這就死鎖了
解決方法:
這種死鎖是因爲你的程序的BUG產生的,除了調整你的程序的邏輯別無他法
仔細分析你程序的邏輯,
1:儘可能避免同時鎖定兩個資源
2: 必須同時鎖定兩個資源時,要保證在任什麼時候刻都應該按照相同的順序來鎖定資源.
表現二:
用戶A讀一條紀錄,而後修改該條紀錄
這是用戶B修改該條紀錄
這裏用戶A的事務裏鎖的性質由共享鎖企圖上升到獨佔鎖(for update),而用戶B裏的獨佔鎖因爲A有共享鎖存在因此必須等A釋
放掉共享鎖,而A因爲B的獨佔鎖而沒法上升的獨佔鎖也就不可能釋放共享鎖,因而出現了死鎖。
這種死鎖比較隱蔽,但其實在稍大點的項目中常常發生。
解決方法:
讓用戶A的事務(即先讀後寫類型的操做),在select 時就是用Update lock
語法以下:
select * from table1 with(updlock) where ....
如何將數據庫中被鎖表解鎖
做者:佚名 文章來源:未知 點擊數:106 更新時間:2005-12-25
我 們在操做數據庫的時候,有時候會因爲操做不當引發數據庫表被鎖定,這麼咱們常常不知所措,不知怎麼給這些表解鎖,在pl/sql Developer工具的的菜單「tools」裏面的「sessions」能夠查詢如今存在的會話,可是咱們很難找到那個會話被鎖定了,想找到因此被鎖的 會話就更難了,下面這叫查詢語句能夠查詢出因此被鎖的會話。以下:
SELECT sn.username, m.SID,sn.SERIAL#, m.TYPE,
DECODE (m.lmode,
0, 'None',
1, 'Null',
2, 'Row Share',
3, 'Row Excl.',
4, 'Share',
5, 'S/Row Excl.',
6, 'Exclusive',
lmode, LTRIM (TO_CHAR (lmode, '990'))
) lmode,
DECODE (m.request,
0, 'None',
1, 'Null',
2, 'Row Share',
3, 'Row Excl.',
4, 'Share',
5, 'S/Row Excl.',
6, 'Exclusive',
request, LTRIM (TO_CHAR (m.request, '990'))
) request,
m.id1, m.id2
FROM v$session sn, v$lock m
WHERE (sn.SID = m.SID AND m.request != 0) --存在鎖請求,即被阻塞
OR ( sn.SID = m.SID --不存在鎖請求,可是鎖定的對象被其餘會話請求鎖定
AND m.request = 0
AND lmode != 4
AND (id1, id2) IN (
SELECT s.id1, s.id2
FROM v$lock s
WHERE request != 0 AND s.id1 = m.id1
AND s.id2 = m.id2)
)
ORDER BY id1, id2, m.request;
經過以上查詢知道了sid和 SERIAL#就能夠開殺了
alter system kill session 'sid,SERIAL#';