2013-03-19 8 views
14

Ich bin wirklich neu in der Windows Azure-Entwicklung und habe eine Anforderung, einige Daten in einer Windows Azure Speichertabelle zu speichern.Die richtige Methode zum Löschen und Neuerstellen einer Windows Azure Storage-Tabelle = Fehler 409 Conflict - Code: TableBeingDeleted

Diese Tabelle wird nur existieren, um einen schnellen Suchmechanismus für einige Dateien bereitzustellen, die sich auf einem azure Speicherlaufwerk befinden.

Deshalb auf Ich hatte geplant, diese Tabelle bei Anwendung bevöl starten (dh in der globalen Anwendung Web-Anwendung starten)

Anstatt zu versuchen, diese Tabelle für Änderungen der Änderungen beizubehalten, die auf das Laufwerk während der Anwendung auftreten könnten Läuft nicht. Oder da es sich bei dieser Festplatte nur um eine VHD von Ressourcen handelt, können wir gelegentlich eine neue VHD hochladen.

Also eher als die Mühe zu versuchen, dies zu erhalten. Es ist ausreichend, dass diese Tabelle bei jedem Anwendungsstart neu erstellt wird.

Ich begann, Code zu erstellen, um zu überprüfen, ob die Tabelle bereits existiert, und wenn sie es löscht, und dann eine neue Tabelle neu erstellen.

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

Ich hatte erwartet, dass dies nicht funktionieren würde. Und ich bekomme folgende Fehlermeldung:

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 

Was ist der richtige Weg, dies zu tun? Gibt es ein Ereignis, das abonniert werden kann, um Sie darüber zu informieren, wann die Tabelle gelöscht wurde? Noch weitere Vorschläge, wie Sie das am besten umsetzen können?

Antwort

25

Von MSDN. „Beachten Sie, dass eine Tabelle zu löschen ist wahrscheinlich abgeschlossen mindestens 40 Sekunden dauern Wenn eine Operation gegen den Tisch versucht wird, während es gelöscht wurde, kehrt die Service-Statuscode 409 (Konflikt) mit zusätzlichem Fehlerinformation, die anzeigt, dass die Tabelle gelöscht wird. "

Der einzige Weg, damit umzugehen, ist eine Tabelle mit einem anderen Namen zu erstellen. Dies könnte so einfach sein wie das Hinzufügen eines Zeitstempels oder einer GUID zu Ihrem Namen. Sei nur vorsichtig, um deinen Müll aufzuräumen.

+0

Alternativ sein, könnten Sie warten und wieder versuchen, bis das Kommando Create – Igorek

+2

Je nach Größe der Tabelle und viele anderen Faktoren gelingt, sein, dass könnte eine sehr lange Zeit. – IngisKahn

+0

Das ist wahr, danke für die Korrektur – Igorek

12

Wenn Sie den gleichen Tabellennamen verwenden möchten, können Sie eine Erweiterungsmethode verwenden:

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); 
    } 
} 

ACHTUNG! Seien Sie vorsichtig, wenn Sie diesen Ansatz verwenden, da er den Thread blockiert. Und es kann in den Leerlauf gehen, wenn der Drittanbieter-Dienst (Azure) diese Fehler weiterhin generiert. Der Grund dafür könnte Tabellensperren, Subskriptionsablaufdatum, Serviceverfügbarkeit usw.

+3

Wow, das ist keine gute Idee.Normalerweise versuche ich zu vermeiden, wenn (wahr) wenn die Logik von Diensten Dritter abhängt. while (retryCnt> 0) wäre hier besser. –

+1

Natürlich können Sie einen Timeout-Parameter übergeben oder einen Timeout programmieren. Aber welchen Wert würdest du vorschlagen? 1 Minute, 2 Minuten, 20 Minuten? IngisKahn sagte: "... wird wahrscheinlich mindestens 40 Sekunden dauern." Sie brauchen also einen hohen Wert und Sie wissen nie, ob der Prozess beendet wäre, wenn Sie eine Sekunde länger gewartet hätten. Wenn der Dienst nicht verfügbar ist oder ein anderes Problem besteht, kann ich mir nicht vorstellen, dass MS den gleichen Fehler TableErrorCodeStrings.TableBeingDeleted zurückgibt. Also, wenn jemand eine Zeitüberschreitung hinzufügt, würde ich einen ziemlich hohen Wert vorschlagen. – huha

+0

Sie können die Methode async machen und 'Thread.Sleep (2000)' durch 'erwarten Task.Delay (2000)' ersetzen - der Thread wird auf diese Weise nicht blockiert. – UserControl

Verwandte Themen