2011-07-29 10 views
4

私は、BLOBメタデータストレージとAzure BLOBストレージ用にSQL Azureを実際のBLOBに使用しています。 BLOBの作成/削除は、それらの操作を周囲のTransactionScopeに登録することによって実装されます。これまでのところうまく動作しますが、誰かがロールバックするためにBLOBの内容をダウンロードする必要がなくなる可能性があるDelete-Operation(下記のソースコードを参照)に最適化を推奨できるかどうかは疑問です。Transactional CloudBlobs

public class CloudBlobDeletionEnlistment : CloudBlobBaseEnlistment, 
    IEnlistmentNotification, 
    IDisposable 
{ 
    public CloudBlobDeletionEnlistment(Guid ownerId, string blobId, CloudBlobContainer container, Logger logger, IUserUploadActivity currentUploadActivity) 
    { 
    ctx = new Context { OwnerId = ownerId, BlobId = blobId, Container = container, Logger = logger, CurrentUploadActivity = currentUploadActivity }; 
    } 

    public ~CloudBlobDeletionEnlistment() 
    { 
    Dispose(false); 
    } 

    public class Context 
    { 
    public Guid OwnerId; 
    public string BlobId; 
    public string ContentFileName; 
    public string MimeType; 
    public bool IsCompressed; 
    public CloudBlobContainer Container; 
    public Logger Logger; 
    public IUserUploadActivity CurrentUploadActivity; 
    } 

    private readonly Context ctx; 
    private CloudBlob blob; 

    public void Prepare(PreparingEnlistment preparingEnlistment) 
    { 
    blob = ctx.Container.GetBlobReference(ctx.BlobId); 

    // save backup information 
    ctx.ContentFileName = Path.GetTempFileName(); 
    blob.DownloadToFile(ctx.ContentFileName); 
    blob.FetchAttributes(); 
    ctx.MimeType = blob.Metadata[Constants.BlobMetaAttributeContentType]; 
    ctx.IsCompressed = bool.Parse(blob.Metadata[Constants.BlobMetaAttributeCompressed]); 

    // delete it 
    blob.DeleteIfExists(); 

    // done 
    preparingEnlistment.Prepared(); 
    } 

    public void Commit(Enlistment enlistment) 
    { 
    Cleanup(); 

    // done 
    enlistment.Done(); 
    } 

    public void Rollback(Enlistment enlistment) 
    { 
    if (blob != null) 
    { 
     try 
     { 
     blob.UploadFile(ctx.ContentFileName); 
     blob.Metadata[Constants.BlobMetaAttributeContentType] = ctx.MimeType; 
     blob.Metadata[Constants.BlobMetaAttributeCompressed] = ctx.IsCompressed.ToString(); 
     blob.SetMetadata(); 
     } 

     finally 
     { 
     Cleanup(); 
     } 
    } 

    else Cleanup(); 

    // done 
    enlistment.Done(); 
    } 

    public void InDoubt(Enlistment enlistment) 
    { 
    Cleanup(); 

    enlistment.Done(); 
    } 

    void Cleanup() 
    { 
    // delete the temporary file holding the blob content 
    if (!string.IsNullOrEmpty(ctx.ContentFileName) && File.Exists(ctx.ContentFileName)) 
    { 
     File.Delete(ctx.ContentFileName); 
     ctx.ContentFileName = null; 
    } 
    } 

    public void Dispose() 
    { 
    Dispose(true); 
    GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
    if (disposing) 
    { 
     // free managed resources 
    } 

    // free native resources if there are any. 
    Cleanup(); 
    } 
    #endregion 
} 

答えて

1

これは私には、安全なロールバックメカニズムのように見えるしていません - アップロードが失敗する可能性があり、それが発生した場合、あなたのデータの整合性が壊れだろう。

データベースのToBeDeletedテーブルに名前を入れてブロブを削除してから、定期的にいくつかのジョブを設定すると、時々これらのブロブが削除されますか?

+0

これは本当に良い提案です。 –

0

ブロブを作成し、単一のトランザクションコンテキストでメタデータを作成したいと思うようです。これは不可能です。あなたのプログラムロジックは "トランザクション"でなければなりません。

同じことがロジックの削除に適用されます。

+0

もちろん、これはACIDトランザクションの近似にすぎませんが、私の意見では、実際のデータベーストランザクションの外部でそれに取り組むよりも優れています。 –

+0

これは古い質問ですが、プログラムロジックについてはどこかにデザインパターンがありますか?それは車輪を再発明するように見えるので..? – Julian50

関連する問題