2013-05-28 21 views
2

我想發送一個簡單批量的插入操作到Azure表存儲,但似乎整個批處理事務失效,並且使用託管的azure存儲客戶端如果批處理中有單個插入到預先存在的記錄,則ExecuteBatch方法本身會引發異常。 (使用2.0客戶端):通過使用InsertOrMerge避免Azure表存儲批量插入與潛在預先存在的行鍵

public class SampleEntity : TableEntity 
{ 
    public SampleEntity(string partKey, string rowKey) 
    { 
     this.PartitionKey = partKey; 
     this.RowKey = rowKey; 
    } 
} 


var acct = CloudStorageAccount.DevelopmentStorageAccount; 
var client = acct.CreateCloudTableClient(); 
var table = client.GetTableReference("SampleEntities"); 

var foo = new SampleEntity("partition1", "preexistingKey"); 
var bar = new SampleEntity("partition1", "newKey"); 

var batchOp = new TableBatchOperation(); 
batchOp.Add(TableOperation.Insert(foo)); 
batchOp.Add(TableOperation.Insert(bar)); 

var result = table.ExecuteBatch(batchOp); // throws exception: "0:The specified entity already exists." 

將批料級異常但隨後各個操作響應返回204,該特定操作是否插入或合併它。因此,客戶端應用程序似乎不可能保留關於它或羣集中的其他節點是否插入記錄的知識。不幸的是,在我目前的情況下,這種知識對於一些下游同步是必需的。

是否有一些配置或技術允許批處理插入繼續並返回每個項目的特定響應代碼而不拋出一個全局異常?

回答

1

正如你所知道的那樣,因爲batch是一個事務操作,所以你可以得到一個或多或少的一筆交易。批量事務有趣的一點是,您可以獲得批處理中第一個失敗實體的索引。因此,假設你試圖在批處理中插入100個實體,並且第50個實體已經存在於表中,那麼批處理操作將爲您提供失敗實體的索引(本例中爲49)。

有一些配置或技術,允許批量插入 的進行,並返回每個項目的具體響應代碼,而不 拋出一條毯子例外?

我不這麼認爲。一旦第一個實體失敗,交易就會失敗。它甚至不會嘗試處理其他實體。

可能的解決方案(只是想大聲:))

如果我理解正確的話,你的關鍵的要求是,以確定如果實體插入或合併(或更換)。爲此,這種方法將從一批中分離失敗的實體並分別處理它們。在此基礎上,我能想到的兩種方法:

  1. 你可以在這種情況下可能做的是分裂的那批進入3個 批次:第一批將含有49個單位,第二批將包括 僅有1個實體(其中失敗),第三批將包含50個 實體。您現在可以在第一批中插入所有實體,然後決定 您想要對該失敗實體執行什麼操作並嘗試插入第二批 。您需要一遍又一遍地重複此過程直到此操作完成。
  2. 另一個想法是從批次中刪除失敗的實體,然後 重試該批次。所以在上面的例子中,你的第一次嘗試 你會嘗試與100個實體,在你的第二次嘗試,你會嘗試與99 實體等等等等跟蹤失敗的實體全部 while(原因至於他們爲什麼失敗)。一旦批次 操作成功完成,您可以使用所有 失敗的實體。