2013-03-19 7 views
14

Im davvero nuovo per lo sviluppo di Windows Azure e ha l'obbligo di memorizzare alcuni dati in una tabella di archiviazione di Windows Azure.Il modo corretto di eliminare e ricreare una tabella di memoria di Windows ad azione - Errore 409 Conflitto - Codice: TableBeingDeleted

Questa tabella esiste solo per fornire un meccanismo di ricerca rapida ad alcuni file che si trovano sull'unità di archiviazione blu.

Quindi stavo pensando di popolamento questa tabella applicazione start up (ovvero in applicazione globale di applicazioni web start up)

Piuttosto che cercare di mantenere questa tabella per le modifiche dei cambiamenti che potrebbero verificarsi per l'unità mentre l'applicazione non sta correndo. O dato che questa unità è solo un VHD di risorse, potremmo occasionalmente caricare un nuovo VHD.

Quindi, piuttosto che la seccatura di cercare di mantenere questo. è sufficiente che questa tabella venga ricostruita all'avvio di ciascuna applicazione.

Ho iniziato a mettere insieme un codice per controllare se la tabella esiste già, e se lo elimina, e quindi ricreare una nuova tabella.

var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["AzureStorage"].ConnectionString); 
var tableClient = storageAccount.CreateCloudTableClient(); 
var rmsTable = tableClient.GetTableReference("ResourceManagerStorage"); 
rmsTable.DeleteIfExists(); 
rmsTable.Create(); 

Mi aspettavo che ciò non funzionasse. E ottengo il seguente errore:

The remote server returned an error: (409) Conflict. 

HTTP/1.1 409 Conflict 
Cache-Control: no-cache 
Transfer-Encoding: chunked 
Server: Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0 
x-ms-request-id: c6baf92e-de47-4a6d-82b3-4faec637a98c 
x-ms-version: 2012-02-12 
Date: Tue, 19 Mar 2013 17:26:25 GMT 

166 
<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> 
    <code>TableBeingDeleted</code> 
    <message xml:lang="en-US">The specified table is being deleted. Try operation later. 
RequestId:c6baf92e-de47-4a6d-82b3-4faec637a98c 
Time:2013-03-19T17:26:26.2612698Z</message> 
</error> 
0 

Qual è il modo corretto di farlo? C'è un evento che può essere sottoscritto per farti sapere quando la tabella è stata cancellata? Qualche altro suggerimento sul modo migliore per implementarlo?

risposta

25

Da MSDN: "Si noti che l'eliminazione di una tabella richiede almeno 40 secondi. Se si tenta di eseguire un'operazione sulla tabella durante l'eliminazione, il servizio restituisce il codice di stato 409 (Conflitto), con ulteriori informazioni di errore che indicano che la tabella è stata eliminata. "

L'unico modo per risolvere questo problema è creare una tabella con un nome diverso. Questo potrebbe essere semplice come aggiungere un timestamp o GUID al tuo nome. Stai solo attento a ripulire la tua spazzatura.

+0

In alternativa, è possibile attendere e riprovare finché il comando Crea non ha esito positivo. – Igorek

+2

A seconda delle dimensioni della tabella e di molti altri fattori, potrebbe essere molto a lungo. – IngisKahn

+0

Questo è vero, grazie per la correzione – Igorek

12

Se è necessario utilizzare lo stesso nome della tabella è possibile utilizzare un metodo di estensione:

public static class StorageExtensions 
{ 
    public static bool SafeCreateIfNotExists(this CloudTable table, TableRequestOptions requestOptions = null, OperationContext operationContext = null) 
    { 
     do 
     { 
      try 
      { 
       return table.CreateIfNotExists(requestOptions, operationContext); 
      } 
      catch (StorageException e) 
      { 
       if ((e.RequestInformation.HttpStatusCode == 409) && (e.RequestInformation.ExtendedErrorInformation.ErrorCode.Equals(TableErrorCodeStrings.TableBeingDeleted))) 
        Thread.Sleep(1000);// The table is currently being deleted. Try again until it works. 
       else 
        throw; 
      } 
     } while (true); 
    } 
} 

ATTENZIONE! Fai attenzione quando usi questo approccio, perché blocca il thread. E può andare al punto morto se il servizio di terze parti (Azure) continua a generare questi errori. Il motivo potrebbe essere il blocco della tabella, la scadenza dell'abbonamento, l'indisponibilità del servizio, ecc.

+3

Wow, NON è una grande idea.Di solito cerco di evitare mentre (true) quando la logica dipende da servizi di terze parti. while (retryCnt> 0) sarebbe meglio qui. –

+1

Ovviamente è possibile passare qualche parametro di timeout o hard code per un certo timeout. Ma quale valore suggeriresti? 1 minuto, 2 minuti, 20 minuti? IngisKahn ha detto che "... ci vorranno almeno 40 secondi per essere completato." quindi hai bisogno di un valore elevato e non sai mai se il processo sarebbe finito se avessi aspettato un secondo di più. Se il servizio non è disponibile o esiste un altro problema, non riesco a immaginare che MS restituisca lo stesso errore TableErrorCodeStrings.TableBeingDeleted. Quindi se qualcuno aggiunge un timeout suggerisco un valore piuttosto alto. – huha

+0

Puoi rendere il metodo async e sostituire 'Thread.Sleep (2000)' con 'awa Task.Delay (2000)' - il thread non verrà bloccato in questo modo. – UserControl

Problemi correlati