在 ArcSDE 地理數據庫中,多個用戶可以同時讀取和編輯相同數據。爲了能在應用程序(例如 ArcMap)中使用地理數據庫中的數據,應用程序必須按照特定原則工作,即地理數據庫架構在使用地理數據庫內容的任何時候均保持固定,不發生更改。例如,將要素類從地理數據庫添加到地圖時,您和其他用戶都不能更改其架構。從地圖中刪除該要素類並且沒有其他用戶查詢或編輯該要素類後,可以更改其架構。
-----------------------------鎖概念講解------------------------------------------------------
架構鎖定概述
地理數據庫及其數據集很少是靜態的。多數數據集會隨時間編輯和更新。有時,會因爲多種原因添加新數據集和刪除現有數據集。此外,還會對現有數據集進行架構更改 - 添加屬性列、更改拓撲中的規則、添加製圖表達等等。
如果使用單用戶地理數據庫,則很容易進行這些更改,而且無需考慮操作可能對其他用戶的影響。但是,如果其他用戶正在訪問和使用要對其進行更改的同一個地理數據庫,則需要建立一些工作流以進行架構更改。例如,要在不影響其他用戶的情況下進行更改,可安排在其他用戶離開系統時執行架構工作。
ArcGIS 提供一些自動架構鎖定機制來幫助管理地理數據庫更改。計劃工作時考慮這些機制非常有用。
共享鎖
ArcGIS 將自動獲取使用中的單個數據集上的共享鎖,例如,當用戶編輯或查詢要素類或表的內容時。使用該機制可以使其他用戶無法對使用中的基礎數據集及其架構進行更改。
可以在任何時間對單個要素類或表建立任何數量的共享鎖。當使用 ArcGIS 修改地理數據庫架構(例如,添加字段或更改規則)時,ArcGIS 會嘗試在被更改的數據上建立排他鎖。但是,如果該數據集上有共享鎖,則無法建立排他鎖。
排他鎖
排他鎖用於鎖定地理數據庫中的數據集以防止其他用戶使用,以便對數據集進行必要的更改,例如,更改數據集的架構。當具有適當權限的用戶開始更改地理數據庫中的數據集時,ArcGIS 會自動在單個屬性表、要素類表、柵格表或其他數據集上建立排他鎖。
如果用戶想更改地理數據庫架構,則該用戶使用的特定數據集不能被其他用戶使用。換句話說,要對數據集進行更改,該數據集上就不能存在共享鎖。
-----------------------------鎖問題的解決------------------------------------------------------
從上面的信息我們可以看到,儘管ArcSDE有版本的概念,但是在編輯數據,編輯結構還是使用了鎖的概念,往往有用戶會有這樣的疑問,爲什麼我的服務器並沒有其他用戶連接,怎麼我在做一些操作的時候,仍然會有一些圖層被鎖定,狀態被鎖定的提示。
其實在SDE用戶下有這麼關於鎖的四張表:
- OBJECT_LOCKS
- STATE_LOCKS
- LAYER_LOCKS
- TABLE_LOCKS
一般在多用戶編輯或者一個用戶開啓多個ArcMap對同一個同層或者多個圖層進行編輯時都會在這些表裏面的寫東西,一般我們將圖層加載到ArcMap中會往TABLE_LOCKS裏面寫信息,如果我們進行版本編輯事務的開啓,會往STATE_LOCKS表裏面寫信息,其他兩個表什麼時候寫信息具體不詳.....
感興趣在後面有介紹............
情況一:如果該數據庫只有你自己這個用戶來操作出現了鎖的問題,用戶如果可以重啓ArcSDE服務,可以嘗試重啓ArcSDE服務,看是否可以解決,如果不能解決,那麼可以將這四個表中的信息直接使用數據庫的方法刪除即可。
注意:重啓ArcSDE服務的方式僅限定於你的測試庫或者你肯定知道只有你一個人進行編輯而沒有多用戶的操作,但是現實業務中往往是多用戶併發,如果出現鎖現象,首先要搞清楚狀況,不能盲目的去重啓服務,如果確定是無效的鎖的問題,可以使用下面的方法處理。
情況二:如果是多用戶併發編輯,在你操作時提示鎖的問題,用戶可以查看連接用戶的信息,自己來設置條件刪除。
比如我們可以查看某個SDE服務下的用戶信息主要是查看SDE_ID信息
- C:\Users\Administrator>sdemon -o info -I users -s 192.168.220.165 -i 5151 -p sde
- ArcSDE Instance 5151 Registered Server Tasks on 192.168.220.165 at Mon Mar 12 15:44:16 2012
- ------------------------------------------------------------------------------
- S-ID S-PID User Conn Client Machine:OS Started
- ----- ----- -------- ---- -------------------------------- -------------------
- 1057 6027 SDE AS esrimakl:Win32:XDR Thu Mar 01 08:35:56
- 1114 14260 SDE AS esrimakl:Win32:XDR Mon Mar 12 11:39:20
- 1070 10634 SDE AS esrimakl:Win32:XDR Mon Mar 05 08:23:43
- 1043 26301 SDE AS esrimakl:Win32:XDR Wed Feb 29 09:49:48
- 1088 7564 SDE DC w2008s101:Win32 Wed Mar 07 16:48:10
- 1102 24604 SDE AS esrimakl:Win32:XDR Fri Mar 09 10:12:28
- 1039 27577 SDE AS esrimakl:Win32:XDR Tue Feb 28 16:54:20
- 1053 3936 SDE AS esrimakl:Win32:XDR Wed Feb 29 15:16:11
- 1063 11507 SDE AS esrimakl:Win32:XDR Thu Mar 01 11:35:35
- 1090 840 SDE AS esrichinazs:Win32:XDR Wed Mar 07 17:57:48
- 1068 6631 SDE AS esrichinazs:Win32:XDR Fri Mar 02 16:44:03
- 1069 10632 SDE AS esrimakl:Win32:XDR Mon Mar 05 08:23:43
- 1109 12864 SDE AS esrimakl:Win32:XDR Mon Mar 12 10:52:52
- 1036 13221 SDE AS esrimakl:Win32:XDR Tue Feb 28 09:01:50
- 1112 9664 SDE DC esrimakl:Win32 Mon Mar 12 11:38:54
- 1062 11477 SDE AS esrimakl:Win32:XDR Thu Mar 01 11:34:38
- SQL> select * from layer_locks;
- 未選定行
- SQL> select * from object_locks;
- 未選定行
- SQL> select * from state_locks;
- SDE_ID STATE_ID A L
- ---------- ---------- - -
- 1114 100 N S
- 1057 100 N S
- 1070 100 N S
- 1043 100 N S
- 1088 100 N S
- 1102 100 N S
- 1039 100 N S
- 1053 100 N S
- 1063 100 N S
- 1090 100 N S
- 1068 100 N S
- SDE_ID STATE_ID A L
- ---------- ---------- - -
- 1069 100 N S
- 1109 100 N S
- 1036 100 N S
- 1112 100 N S
- 1062 100 N S
- 已選擇16行。
- SQL> select * from table_locks;
- SDE_ID REGISTRATION_ID LO
- ---------- --------------- --
- 1112 263 S
- 1112 264 S
- 1112 265 S
- 1062 248 S
- 1062 252 S
- 1062 249 S
- 1062 250 S
- 1062 251 S
- 1062 253 S
- 1062 254 S
- 1062 255 S
- ..........
- SDE_ID REGISTRATION_ID LO
- ---------- --------------- --
- 1062 256 S
- 1062 257 S
- 1062 258 S
- 1062 259 S
- 1062 260 S
- 1062 261 S
- 1062 262 S
- 1062 263 S
- 1062 264 S
- 1062 265 S
- 已選擇241行。
而且ArcSDE也提供了相關的存儲過程來對相關的鎖類型表進行刪除
- begin
- -- Call the procedure
- lock_util.delete_layer_locks_by_sde_id(sde_id => :sde_id);
- end;
- begin
- -- Call the procedure
- lock_util.delete_table_locks_by_sde_id(sde_id => :sde_id);
- end;
- begin
- -- Call the procedure
- lock_util.delete_object_locks_by_sde_id(sde_id => :sde_id);
- end;
- begin
- -- Call the procedure
- lock_util.delete_state_locks_by_sde_id(sde_id => :sde_id);
- end;
- begin
- -- Call the procedure
- lock_util.delete_all_locks_by_sde_id(sde_id => :sde_id);
- end;
- --直接清空所有的孤兒鎖
- begin
- -- Call the procedure
- lock_util.delete_all_orphaned_locks;
- end;
使用以上方法,就可以非常方便的對指定的某個SDE連接進行鎖的刪除了。