【问题标题】:Transactionable objects in C#?C# 中的可交易对象?
【发布时间】:2012-12-30 09:10:21
【问题描述】:

看代码:

class MyClass {  public static int g=1;}

using (TransactionScope tsTransScope = new TransactionScope())
{
    //Do stuff here
    MyClass.g=999;
    tsTransScope.Complete();
}
  • 查看“在此处进行操作”部分:我可以在其中写入什么类型对象,以便它们可以可交易 ?.我已经知道我可以编写 ADO 命令,并且它们会在必要时回滚/提交。但是通过C# POV:类必须具有什么实现才能Transactionable(实现一些接口或什么?)

  • 如果它是 TransactionScope,在 using 子句内(即 try + finally),逻辑表示如果有回滚:MyClass.g 应该返回其值1. 然而。这没有发生。 所以我想这与第一个问题有关。我怎样才能使 MyClass Transactionable

【问题讨论】:

  • 有一些接口需要实现事务性,回滚或者评论的时候需要做点什么,是吗?
  • @MSakherSawan 我假设有 .这实际上是我的问题。

标签: c# .net ado.net transactionscope


【解决方案1】:

你应该实现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 添加了 G 守门员 :) *

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

【讨论】:

  • 所以实际上在实现这个接口时,g 的值为 1。cool
  • 您应该编写将值返回到其主值的逻辑!我正在写一个小而好的例子!
  • 所以在 .complete 之前写 throw new Exception() 实际上会带回 1 的值(而不是 999)——在我的例子中。对吗?
  • 我会为你的 g 添加一个例子 :)
  • 添加了一个类以将 g 返回到它的值!并添加了两个链接。
猜你喜欢
  • 2014-04-09
  • 2022-08-13
  • 2022-07-22
  • 1970-01-01
  • 2013-01-09
  • 2011-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多