2011-07-29 54 views
4

我對Blob元數據存儲和Azure Blob存儲使用SQL Azure來處理實際的blob。 Blob的創建/刪除是通過在環境TransactionScope中使用這些操作來實現的。到目前爲止一切正常,但我想知道是否有人可以推薦優化刪除操作(請參閱下面的源代碼),可能會擺脫爲了回滾下載blob內容的要求。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表中來刪除你的blob,然後你設置了一些常規作業,不時刪除這些blob?

+0

這是一個非常好的建議。 –

0

它看起來像我想要創建一個blob並在單個事務上下文中創建元數據。這不可能。你的程序邏輯必須「成爲交易」。

這同樣適用於刪除邏輯。

+0

當然,這只是ACID交易的近似值,但在我看來,它比在實際的數據庫交易之外解決問題要好。 –

+0

這是一個古老的問題,但關於程序邏輯,有沒有設計模式?因爲它看起來像是再造輪子..? – Julian50