2012-12-30 63 views
5

看代碼:C#中的可交易對象?

class MyClass { public static int g=1;} 

using (TransactionScope tsTransScope = new TransactionScope()) 
{ 
    //Do stuff here 
    MyClass.g=999; 
    tsTransScope.Complete(); 
} 
  • 在看「做的東西在這裏」一節:我可以在那裏寫什麼對象的類型使他們能夠Transactionable? 。我已經知道我可以編寫ADO命令,並且在需要時將會回滾/提交。但通過C# POV:什麼實現應該一類必須有爲了Transactionable

  • 如果是TransactionScope因爲它叫,一個using子句中(這是嘗試(實現一些界面什麼的?) + finally),邏輯表示如果回滾:MyClass.g應該返回其值1.但是。這沒有發生。 所以我想這與第一個問題有關。我怎樣才能讓MyClass 可交易

+0

有一些接口來實現是transactionable,你需要做的事情回滾或評論時,做u? –

+0

@MSakherSawan我_assume_有。這是我的問題。 –

回答

8

你應該實現System.Transactions.IEnlistmentNotification接口,this文章和this可以幫助你

對於現成的事務性內存存儲,有(Software transactional memory)和STM.NET它不是一個最終的東西,但微軟正在努力!

一個小例子:

using System.IO; 
using System.Text; 
using System.Transactions; 

namespace Sakher.Transactions 
{ 
    public class TsansactionalFileWriter 
    { 
     private FileTransactionEnlistment fileTransactionEnlistment = new FileTransactionEnlistment(); 
     public TsansactionalFileWriter(string filePath) 
     { 
      fileTransactionEnlistment.FilePath = filePath; 
      Transaction.Current.EnlistVolatile(fileTransactionEnlistment, EnlistmentOptions.None); 
     } 

     public void AppendText(string text) 
     { 
      fileTransactionEnlistment.Content.Append(text); 
     } 

     public void WriteAllText(string text) 
     { 
      fileTransactionEnlistment.Content = new StringBuilder(text); 
     } 
    } 

    public class FileTransactionEnlistment : IEnlistmentNotification 
    { 
     public string FilePath { get; set; } 
     public StringBuilder Content { get; set; } 

     public FileTransactionEnlistment() 
     { 
      Content = new StringBuilder(); 
     } 

     public void Commit(Enlistment enlistment) 
     { 
      File.WriteAllText(FilePath, Content.ToString()); 
     } 

     public void InDoubt(Enlistment enlistment) 
     { 

     } 

     public void Prepare(PreparingEnlistment preparingEnlistment) 
     { 
      //You can create the file here 
      preparingEnlistment.Prepared(); 
     } 

     public void Rollback(Enlistment enlistment) 
     { 
      //Do ssomething when the transaction is rolled-back (You may delete the file if you have created it!) 
     } 
    } 

} 

消費代碼:

 using (TransactionScope tr = new TransactionScope()) 
     { 
      TsansactionalFileWriter writer = new TsansactionalFileWriter("c:\\myFile.txt"); 
      writer.AppendText("sdfgssdfgsdf"); 
      tr.Complete(); 
     } 

* EDTI:新增摹飼養人ROYI :) *

using System.Transactions; 

namespace Sakher.Transactions 
{ 
    public class Royi_s_gReturnerClass 
    { 
     private GReturnerEnlistment fileTransactionEnlistment = new GReturnerEnlistment(); 
     public Royi_s_gReturnerClass() 
     { 
      Transaction.Current.EnlistVolatile(fileTransactionEnlistment, EnlistmentOptions.None); 
     } 
    } 

    public class GReturnerEnlistment : IEnlistmentNotification 
    { 
     public int GOldValue { get; set; } 

     public GReturnerEnlistment() 
     { 
      GOldValue = MyClass.g; 
     } 

     public void Commit(Enlistment enlistment) 
     { 

     } 

     public void InDoubt(Enlistment enlistment) 
     { 

     } 

     public void Prepare(PreparingEnlistment preparingEnlistment) 
     { 
      preparingEnlistment.Prepared(); 
     } 

     public void Rollback(Enlistment enlistment) 
     { 
      MyClass.g = GOldValue; 
     } 
    } 

} 

您的代碼會:

class MyClass { public static int g=1;} 

using (TransactionScope tsTransScope = new TransactionScope()) 
{ 
    Royi_s_gReturnerClass returner = new Royi_s_gReturnerClass(); 
    //Do stuff here 
    MyClass.g=999; 
    tsTransScope.Complete(); 
} 
+1

所以實際上當實現這個接口時,g的值將會是1. cool –

+0

你應該編寫返回值爲其主值的邏輯!我正在寫一個很好的例子! –

+0

謝謝你。好答案。 –