批次處理可讓您在單一要求中執行多項作業,而不需個別提交每項作業。
注意:您必須使用最新版本的 Google Data API 用戶端程式庫才能執行批次作業。JavaScript 用戶端程式庫不支援批次作業。
目標對象
本文適用於想透過批次處理單一要求提交多項作業的程式設計師。
這份文件假設您已熟悉 GData Java 用戶端程式庫的使用方式。本文件中的範例說明如何使用 Java 用戶端程式庫執行批次作業。
本文中的範例僅適用於 Google Base Data API。但其他服務也可能提供批次功能。
注意事項:其他用戶端程式庫的通訊協定和一般程序相同,但執行批次要求的特定方法可能不同。詳情請參閱用戶端程式庫專屬說明文件。
簡介
您可以使用 GData 批次動態饋給來收集多個插入、更新、刪除和查詢作業,然後一次提交及執行這些作業。
舉例來說,以下資訊提供包含四個作業:
<feed> <entry> <batch:operation type="insert"/> ... what to insert ... </entry> <entry> <batch:operation type="update"/> ... what to update ... </entry> <entry> <batch:operation type="delete"/> ... what to delete ... </entry> <entry> <batch:operation type="query"/> ... what to query ... </entry> </feed>
服務會盡可能執行要求的所有變更,並傳回用來評估每項作業成功或失敗狀態的狀態資訊。
服務會嘗試在批次中執行每項作業,即使批次中包含的部分作業失敗。
提交批次要求
批次要求應以 HTTP POST 的形式傳送至批次網址。不同的動態饋給支援不同的批次作業。唯讀動態饋給僅支援查詢。
如要查詢特定動態饋給是否支援批次作業,您可以查詢該動態饋給。如果動態饋給包含動態饋給層級的「批次」連結關係,表示動態饋給支援批次作業。
「批次」連結關係是包含 rel="http://schemas.google.com/g/2005#batch"
的 <link>
元素。連結關係的 href
屬性定義用於張貼批次作業動態饋給文件的網址。
舉例來說,如果您執行:GET http://www.google.com/base/feeds/items
(一般 Google Base 的「items」動態饋給),您可能會收到以下回應:
<feed xmlns=... <id>http://www.google.com/base/feeds/items</id> <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.google.com/base/feeds/items"/> <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="http://www.google.com/base/feeds/items"/> <link rel="http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="http://www.google.com/base/feeds/items/batch"/> ... </feed>
在這個範例中,批次網址為 http://www.google.com/base/feeds/items/batch
。
編寫批次作業動態饋給
作業動態饋給含有要插入、更新、刪除或查詢的項目清單。每項作業都會由 <batch:operation type="insert|update|delete|query"/>
元素定義。
這個元素可以是 <feed>
元素的直接子項、動態饋給中任何項目的直接子項,或兩者皆是。包含在項目中,會指定要對特定項目執行的作業。加入動態饋給時,這個元素會指定在沒有 <batch:operation/>
元素的任何項目中執行的預設作業。
當項目和動態饋給都未指定作業時,預設作業會是 insert
。
應用程式不可在單一批次動態饋給中,為同一項項目套用多項作業。如果您為同一個項目指定多個作業,系統會無法判定結果。
為提高效能,系統可能不會按照要求的順序處理作業。不過,最終結果一律與處理順序相同。
在 XML 中,您傳送至伺服器的位元組數量不得超過 1 MB (1,048,576 位元組)。一般來說,您可以要求的作業數沒有限制,只要總位元組大小不超過 1 MB 即可。不過,部分服務可能會設有額外限制。
如要使用批次作業,您必須在 <f
eed>
元素中加入批次命名空間宣告做為屬性:
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" ... xmlns:batch="http://schemas.google.com/gdata/batch">
插入作業
插入作業如下所示:
<batch:operation type="insert">
插入作業相當於發布 POST 的項目。作業成功後,系統會傳回整個項目內容,包含更新的文件 <id>
元素和 <batch:status code="201"/>
元素。
以下是插入要求成功的範例:
<entry> <title type="text">...</title> <content type="html">...</content> <batch:id>itemA</batch:id> <batch:operation type="insert"/> <g:item_type>recipes</g:item_type> ... </entry>
以下是插入成功要求的回應範例:
<entry> <batch:status code="201"/> <batch:id>itemA</batch:id> <batch:operation type="insert"/> <id>http://www.google.com/base/feeds/items/17437536661927313949</id> <link rel="self" type="application/atom+xml" href="http://www.google.com/base/feeds/items/17437536661927313949"/> <title type="text">...</title> <content type="html">...</content> <g:item_type>recipes</g:item_type> ... </entry>
更新作業
<batch:operation type="update">
更新作業相當於在該項目的 <id>
元素參照的網址上執行 PUT
。作業成功後,系統會使用 <batch:status
code="200"/>
元素傳回整個項目內容。
注意事項:使用某些動態饋給時,您還需要透過批次更新要求來指定該項目的 rel="edit"
連結。這些動態饋給包含支援 Google Data 通訊協定 v1 樣式的樂觀並行,以及不含網址 ID 的動態饋給。
以下是更新要求的範例:
<entry> <id>http://www.google.com/base/feeds/items/17437536661927313949</id> <batch:operation type="update"/> ... </entry>
以下是成功回應的範例:
<entry> <batch:status code="200"/> <id>http://www.google.com/base/feeds/items/17437536661927313949</id> <batch:operation type="update"/> ... </entry>
注意:某些資訊提供使用強大的 ETag,可防止您不小心修改其他人的變更。針對這些資訊提供中某個項目的批次更新要求時,您必須在該項目的 gd:etag
屬性中提供 ETag 值。例如,<entry gd:etag="'F08NQAxFdip7IWA6WhVR'">...<batch:operation type="update"/>...
部分更新作業
對於支援部分更新的動態饋給,您還可以在批次要求中使用。部分更新作業相當於在該項目 <id>
元素參照的網址上執行 PATCH
。作業成功後,系統會使用 <batch:status
code="200"/>
元素傳回整個項目內容。
注意事項:使用某些動態饋給時,您還需要透過批次更新要求來指定該項目的 rel="edit"
連結。這些動態饋給包含支援 Google Data 通訊協定 v1 樣式的樂觀並行,以及不含網址 ID 的動態饋給。
<batch:operation type="patch"/>
以下是部分更新要求的範例:
<entry gd:fields="content" gd:etag="FE8LQQJJeSp7IWA6WhVa"> <id>http://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID</id> <batch:operation type="patch"/> <title>New title</title> </entry>
以下是成功回應的範例:
<entry gd:etag="FE8LQQJJeSp7IWA6WhVa"> <batch:status code="200"/> <id>http://www.google.com/calendar/feeds/jo@gmail.com/private/full/entryID</id> <batch:operation type="patch"/> <title>New title</title> <content></content> ...rest of the entry... </entry>
可刪除作業
<batch:operation type="delete">
刪除作業相當於在該項目 <id>
元素參照的網址上執行 DELETE
。如果是刪除作業,只需傳送 <id>
元素即可刪除項目。系統會忽略您在 batch:
命名空間以外元素的任何其他資訊。作業成功時,系統會傳回含有相同 ID 的 <batch:status
code="200"/>
元素。
注意:使用某些資訊提供時,您還需要透過批次刪除要求來指定該項目的 rel="edit"
連結。這些動態饋給包含支援 Google Data 通訊協定 v1 樣式的樂觀並行,以及不含網址 ID 的動態饋給。
以下是刪除要求的範例:
<entry> <batch:operation type="delete"/> <id>http://www.google.com/base/feeds/items/17437536661927313949</id> </entry>
以下是成功回應的範例:
<entry> <batch:operation type="delete"/> <id>http://www.google.com/base/feeds/items/17437536661927313949</id> <batch:status code="200" reason="Success"/> </entry>
注意:某些資訊提供使用強大的 ETag,可防止您不小心修改其他人的變更。為這些資訊提供項目中的某個項目提出大量刪除要求時,您必須在該項目的 gd:etag
屬性中提供 ETag 值。例如,<entry gd:etag="'F08NQAxFdip7IWA6WhVR'">...<batch:operation type="delete"/>...
查詢作業
<batch:operation type="query">
查詢作業相當於在該項目 <id>
元素參照的網址上執行 GET
。作業成功後,系統會傳回整個項目內容。
注意事項:使用某些資訊提供時,您也需要以批次查詢要求指定該項目的 rel="self"
連結。屆時如果動態饋給的 ID 不是網址,就屬於這類動態饋給。
以下是查詢要求的範例:
<entry> <id>http://www.google.com/base/feeds/items/1743753666192313949</id> <batch:operation type="query"/> </entry>
以下是成功回應的範例:
<entry> <id>http://www.google.com/base/feeds/items/1743753666192313949</id> <batch:operation type="query"/> <batch:status code="200" reason="Success"/> ... </entry>
追蹤作業
GData 輸入結果不一定會與要求的順序傳回。您可以使用 ID,在其生命週期中追蹤作業。
更新、刪除及查詢作業時,您可以使用項目本身的 ID 來追蹤作業。
如果是插入作業,由於沒有 ID,您可以傳入作業 ID。這個 ID 可用來將結果項目連結至要求項目。作業 ID 會透過 <batch:id>
元素傳遞。
GData 會針對每項作業傳回回應,指出作業成功或失敗。每個回應都會找出相關項目。針對更新、刪除或查詢作業或成功插入作業,系統一律會傳回項目 ID。如果您已指定批次 ID,系統會一併傳回這個 ID。由於插入作業失敗時沒有相關聯的項目 ID,因此只會傳回批次 ID。
使用每項作業的 ID 時,您只能重試失敗的作業,而不必重新提交整批作業。
<batch:id>
的內容是用戶端定義的字串值,會在對應的回應項目中回呼。您可以指定任何值,協助用戶端將回應與原始要求中的項目建立關聯。即使作業失敗,此元素也會依照對應項目原樣進行回音。GData 絕不會儲存或解讀這個批次 ID 的內容。
以下為批次作業資訊提供的範例。請注意,<batch:id>
元素會將這項作業標示為 itemB
。
<entry> <title type="text">...</title> <content type="html">...</content> <batch:id>itemB</batch:id> <batch:operation type="insert"/> <g:item_type>recipes</g:item_type> </entry>
以下範例顯示回應此作業所傳回的批次狀態項目。
<entry> <id>http://www.google.com/base/feeds/items/2173859253842813008</id> <published>2006-07-11T14:51:43.560Z</published> <updated>2006-07-11T14:51: 43.560Z</updated> <title type="text">...</title> <content type="html">...</content> <link rel="self" type="application/atom+xml" href="http://www.google.com/base/feeds/items/2173859253842813008"/> <link rel="edit" type="application/atom+xml" href="http://www.google.com/base/feeds/items/2173859253842813008"/> <g:item_type>recipes</g:item_type> <batch:operation type="insert"/> <batch:id>itemB</batch:id> <batch:status code="201" reason="Created"/> </entry>
處理狀態碼
狀態碼由下列元素表示:
<batch:status code="200|201|404|500|..." reason="reason" [content-type="type"]/>
回應資訊提供中的每個項目都包含一個 <batch:status>
元素。這個元素會描述執行這項作業時發生的情況。這個程式碼會模擬如果傳送的是個別作業,而非批次批次傳送時傳送的 HTTP 回應。
您必須查看回應中每個項目的 <batch:status>
元素,看看相關聯的作業是否已成功處理完畢。code="n"
屬性包含 GData 狀態碼。
狀態說明
<batch:status>
元素的 reason="reason"
屬性包含更詳細的作業狀態說明。
內容類型
<batch:status>
元素中的 content-type="type"
屬性包含 <batch:status>
元素所含資料的 MIME 類型。這會對應至 HTTP 狀態回應的 Content-Type
標頭。此屬性為選用項目。
設定內容類型後,<batch:status>
元素的主體會說明處理該項目時發生錯誤。
識別服務中斷的作業
服務中斷時,回應中會包含以下元素:
<batch:interrupted reason="reason" success="N" failures="N" parsed="N">
這個元素表示批次處理作業中斷,所有嘗試中斷中斷的原因均失敗。部分項目可能已順利處理完畢。所有未於這個時間點前回報為成功的項目均遭到捨棄。
這個元素極為罕見,通常代表要求內文中傳送的動態饋給格式不正確。
與 <batch:status>
元素一樣,您可以在 reason
屬性中找到短狀態碼。系統也可能會在元素內顯示較長的回應。
批次作業和狀態資訊提供範例
以下為可傳送到伺服器的批次作業資訊提供。這項資訊提供會要求伺服器刪除兩個項目,並新增兩個項目。請注意, <feed>
元素必須包含批次命名空間處理,如下方範例所示。
POST : http://www.google.com/base/feeds/items/batch <?xml version="1.0" encoding="UTF-8"?> <feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:g="http://base.google.com/ns/1.0" xmlns:batch="http://schemas.google.com/gdata/batch"> <title type="text">My Batch Feed</title> <entry> <id>http://www.google.com/base/feeds/items/13308004346459454600</id> <batch:operation type="delete"/> </entry> <entry> <id>http://www.google.com/base/feeds/items/17437536661927313949</id> <batch:operation type="delete"/> </entry> <entry> <title type="text">...</title> <content type="html">...</content> <batch:id>itemA</batch:id> <batch:operation type="insert"/> <g:item_type>recipes</g:item_type> </entry> <entry> <title type="text">...</title> <content type="html">...</content> <batch:id>itemB</batch:id> <batch:operation type="insert"/> <g:item_type>recipes</g:item_type> </entry> </feed>
假設這兩個插入項目都正常運作,但兩個刪除作業中的其中一個失敗。在這種情況下,批次狀態資訊提供可能如下所示。請注意,相較於批次作業動態饋給,這些項目已重新排序。
<?xml version="1.0" encoding="UTF-8"?> <feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:g="http://base.google.com/ns/1.0" xmlns:batch="http://schemas.google.com/gdata/batch"> <id>http://www.google.com/base/feeds/items</id> <updated>2006-07-11T14:51:42.894Z</updated> <title type="text">My Batch</title> <link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.google.com/base/feeds/items"/> <link rel="http://schemas.google.com/g/2005#post" type="application/atom+xml" href="http://www.google.com/base/feeds/items"/> <link rel=" http://schemas.google.com/g/2005#batch" type="application/atom+xml" href="http://www.google.com/base/feeds/items/batch"/> <entry> <id>http://www.google.com/base/feeds/items/2173859253842813008</id> <published>2006-07-11T14:51:43.560Z</published> <updated>2006-07-11T14:51: 43.560Z</updated> <title type="text">...</title> <content type="html">...</content> <link rel="self" type="application/atom+xml" href="http://www.google.com/base/feeds/items/2173859253842813008"/> <link rel="edit" type="application/atom+xml" href="http://www.google.com/base/feeds/items/2173859253842813008"/> <g:item_type>recipes</g:item_type> <batch:operation type="insert"/> <batch:id>itemB</batch:id> <batch:status code="201" reason="Created"/> </entry> <entry> <id>http://www.google.com/base/feeds/items/11974645606383737963</id> <published>2006-07-11T14:51:43.247Z</published> <updated>2006-07-11T14:51: 43.247Z</updated> <title type="text">...</title> <content type="html">...</content> <link rel="self" type="application/atom+xml" href="http://www.google.com/base/feeds/items/11974645606383737963"/> <link rel="edit" type="application/atom+xml" href="http://www.google.com/base/feeds/items/11974645606383737963"/> <g:item_type>recipes</g:item_type> <batch:operation type="insert"/> <batch:id>itemA</batch:id> <batch:status code="201" reason="Created"/> </entry> <entry> <id>http://www.google.com/base/feeds/items/13308004346459454600</id> <updated>2006-07-11T14:51:42.894Z</updated> <title type="text">Error</title> <content type="text">Bad request</content> <batch:status code="404" reason="Bad request" content-type="application/xml"> <errors> <error type="request" reason="Cannot find item"/> </errors> </batch:status> </entry> <entry> <id>http://www.google.com/base/feeds/items/17437536661927313949</id> <updated>2006-07-11T14:51:43.246Z</updated> <content type="text">Deleted</content> <batch:operation type="delete"/> <batch:status code="200" reason="Success"/> </entry> </feed>
使用 GData Java 用戶端程式庫的批次功能
本節說明如何使用 GData Java 用戶端程式庫的批次功能,提交一組插入、更新和/或刪除要求。
本節提供的範例使用 Google Base API。
除了標準 GData 和 Google Base 類別之外,請先匯入需要的類別:
import com.google.gdata.data.batch.*; import com.google.api.gbase.client.*;
如要提交批次要求,您必須從動態饋給取得批次網址。下列程式碼片段示範如何執行這項作業,假設 feed
是包含動態饋給相關資訊的 GoogleBaseFeed
物件:
Link batchLink = feed.getLink(Link.Rel.FEED_BATCH, Link.Type.ATOM); if (batchLink != null) { URL batchUrl = new URL(batchLink.getHref()); ... // batch handling } else { // batching is not supported for this feed }
下列程式碼片段準備了一個動態饋給,並會在單一作業中插入兩個項目:
GoogleBaseEntry entry1 = new GoogleBaseEntry(); ... // initialize entry 1 content BatchUtils.setBatchId(entry1, "A"); // A is the local batch ID for this entry feed.addEntry(entry1); GoogleBaseEntry entry2 = new GoogleBaseEntry(); ... // initialize entry 2 content BatchUtils.setBatchId(entry2, "B"); // B is the local batch ID for this entry feed.addEntry(entry2);
這個範例中的程式碼絕不會明確指出要為這些項目執行的動作為 insert
。您不需要指定,因為插入功能是預設的作業。
如要傳送批次動態饋給並接收結果,請呼叫 Service.batch
方法。
與 Service.insert
一樣,Service.batch
會傳回插入新 <atom:id>
值的插入項目。傳回的項目會包含在 GoogleBaseFeed
物件中。
如果您想在插入其他兩個項目時同時刪除第三個項目 (您已擷取並儲存在 entry3
中),可以使用以下程式碼:
GoogleBaseEntry toDelete = new GoogleBaseEntry(); toDelete.setId(entry3.getId()); BatchUtils.setBatchOperationType(toDelete, BatchOperationType.DELETE); feed.addEntry(toDelete); GoogleBaseFeed result = service.batch(batchUrl, feed);
此處的 service
是 com.google.gdata.client.Service
的執行個體。
如要更新項目,請指定 OperationType.UPDATE
,並以需要的變更進行初始化,而不是保留空白。
這些範例使用 Google Base 資料 API。如果您將 service.batch
與其他類型的 GData 服務搭配使用,請將適當的類別、項目和服務類別替換為 GoogleBaseFeed
、GoogleBaseEntry
和 GoogleBaseService
類別。
批次作業的結果不一定會按照要求的順序傳回。在上述範例中,結果動態饋給很可能包含 entry2
,後面接著 entry1
。請勿假設以任何特定順序傳回項目。
批次作業動態饋給應為每個插入作業指派專屬的批次 ID,如追蹤作業中所述。在上述範例中,批次 ID 為 A
和 B
。因此,如要瞭解要求作業的狀態,請重複傳回傳回批次動態饋給中的項目,並比較其批次 ID 或項目 ID,如下所示:
for (GoogleBaseEntry entry : result.getEntries()) { String batchId = BatchUtils.getBatchId(entry); if (BatchUtils.isSuccess(entry)) { if ("A".equals(batchId)) { entry1 = entry; } else if ("B".equals(batchId)) { entry2 = entry; } else if (BatchUtils.getBatchOperationType(entry) == BatchOperationType.DELETE) { System.out.println("Entry " + entry.getId() + " has been deleted successfully."); } } else { BatchStatus status = BatchUtils.getBatchStatus(entry); System.err.println(batchId + " failed (" + status.getReason() + ") " + status.getContent()); } }
傳回的動態饋給中的每個項目都有相關聯的 BatchStatus
物件。
BatchStatus
物件包含 HTTP 傳回代碼和回應,說明項目處理期間發生錯誤的原因。您必須檢查每個項目的 HTTP 傳回碼,以得知作業是否成功。
使用上述方法的便利方法 BatchUtils.isSuccess
完成檢查。在本範例中,這相當於:BatchUtils.getBatchStatus(entry) < 300
。
如要進一步瞭解狀態碼和回應,請參閱處理狀態碼一文。