交談群組鎖定
Service Broker 會使用交談群組鎖定來保證只有一個佇列讀取器,可以在任何指定時間使用一組相關的訊息。Service Broker 會使用交談群組鎖定來保證僅依序處理訊息一次。
所有的交談都屬於交談群組。依預設,每個交談都屬於不同的交談群組,因此會有不同的交談群組識別碼。MOVE CONVERSATION 陳述式會變更交談的交談群組。BEGIN DIALOG CONVERSATION 陳述式包含的選項,可將新交談與現有的交談群組相關聯。如需有關交談群組的詳細資訊,請參閱<交談群組>。
事實上,交談群組鎖定是在一組共用相同交談群組識別碼之訊息上的獨佔鎖定。交談群組鎖定是基於簡單、效率和正確性所設計。取得或釋放交談群組鎖定並沒有明確的命令或是提示。取而代之的是,每個會影響對話方塊或是交談群組的 Service Broker 命令,會自動取得適當的交談群組鎖定。例如,BEGIN DIALOG 陳述式會鎖定新對話方塊所屬的交談群組,而 RECEIVE 陳述式則會鎖定接收訊息所屬的交談群組。
工作階段會在工作階段取得鎖定的交易期間,保存交談群組鎖定。工作階段無法在不同的交易之間保存交談群組鎖定,當交易結束時,會釋放在交易期間取得的所有交談群組鎖定。
鎖定會為交談群組,而不是交談識別碼而發生。因此,鎖定僅適用於交談的某一端,即使起始端和目標是在相同的資料庫中。目標服務所取得的鎖定不會封鎖起始服務,反之亦然。此外,Database Engine 在將內送訊息加入佇列時,不會強制鎖定。當應用程式在訊息所屬的交談群組上具有交談群組鎖定時,Database Engine 會將訊息加入佇列。
就務實的角度來看,這表示只使用從 Service Broker 擷取的識別碼之應用程式,並不需要等待,即可取得 Service Broker 資源的鎖定。大部分的 Service Broker 應用程式是設計成利用由 Service Broker 提供的鎖定。也就是說,大部分的 Service Broker 應用程式,只會使用交談群組識別碼以及已經從相同交易中的 Service Broker 陳述式所取得的交談處理常式。
例如,應用程式通常會從 Service Broker 取得交談群組識別碼、從狀態資料表擷取狀態,然後處理在該交談群組中的交談訊息。一旦應用程式取得交談群組識別碼,應用程式便具有交談群組的鎖定:沒有其他的應用程式執行個體可以取得鎖定。不過,交談群組鎖定不會防止應用程式的其他執行個體接收其他交談群組的訊息,而且不會防止內送訊息到達佇列。
透過此鎖定策略,Service Broker 可以保證按順序的訊息處理。因為只有一個佇列讀取器可以處理指定交談群組的訊息,所以兩個佇列讀取器在相同的交談群組中同時接收訊息並不會有風險。對於特定的交談,RECEIVE 陳述式會按照傳送訊息的順序來傳回訊息,因此多個佇列讀取器可以從佇列處理訊息,而不必明確地協調順序。
因為鎖定會在交談群組而不是在個別交談上作業,所以未在 RECEIVE 陳述式中指定特定交談的佇列讀取器,可能會從屬於相同交談群組的不同交談接收訊息。此外,RECEIVE 陳述式會傳回佇列中下一個可用的訊息,不論該訊息是否屬於在目前交易中目前為解除鎖定或鎖定之交談群組的一部分。若要從特定交談中接收訊息,請在 RECEIVE 陳述式中指定交談處理常式。若要從特定交談群組中接收訊息,請在 RECEIVE 陳述式中指定交談群組識別碼。
由於此鎖定策略,您的應用程式應該在更新應用程式的狀態資料表之前,先取得交談群組鎖定。大部分的情況下,當您的應用程式收到訊息或是取得交談群組時,這將會自動發生。不過,當處理錯誤時,應用程式可能需要在更新狀態資料表以指出錯誤之前,先重新取得交談群組鎖定。如需錯誤處理的詳細資訊,請參閱<Service Broker 的錯誤處理>。
下列陳述式可取得交談群組鎖定: