1

私はこの GUID を使用しました: http://www.c-sharpcorner.com/uploadfile/shivprasadk/wcf-faq-part-5-transactions/ なぜロールバックしないのですか?? 理解できない!

私はサービスとクライアント アプリケーションを持っていますが、このコードの問題点がわかりません。この行を完全に実行してDBに保存した後、

proxy.AddEmployee("Stav", "20");

Age パラメーターに数値を送信しなかったため、次の行で例外がスローされますが、トランザクションは最初の行をロールバックしないため、情報: Stav, 20 がまだ DB に存在します!

proxy.AddEmployee("Stav123", "Not a Number(-->will do Exception)") 

編集 1: AddEmployee 実装を追加します。

クライアント:

static void Main(string[] args)
        {
            ServiceReference1.IJob proxy = new ServiceReference1.JobClient();
            using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
            {
                try
                {
                    proxy.AddEmployee("Stav", "20");
                    proxy.AddEmployee("Stav123", "Not a Number(-->will do Exception) ");//stop the running and show the Exception but keep the stav,20 in DB
                    ts.Complete();
                }
                catch
                {
                    ts.Dispose();
                }
            }
        }

サービス:

[ServiceContract]
    public interface IJob
    {
        [OperationContract]
        [TransactionFlow(TransactionFlowOption.Allowed)]
        void AddEmployee(string Name, string Age);
    }
public class JobImplement:IJob
    {
        [OperationBehavior(TransactionScopeRequired = true)]
        public void AddEmployee(string Name, string Age)
        {
string strConnection = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\stavalfi\Desktop\WCF2\ConsoleApplication4\WCF_DB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
        SqlConnection objConnection = new SqlConnection(strConnection);
        objConnection.Open();
        SqlCommand objCommand = new SqlCommand("INSERT INTO Employee (Name,Age) " + "VALUES ('" + Name + "' ,'" + Age + "')", objConnection);
        objCommand.ExecuteNonQuery();
        objConnection.Close();
        }
    }
static void Main(string[] args)
        {
            WSHttpBinding Basic = new WSHttpBinding();
            Basic.TransactionFlow = true;
            ServiceHost host = new ServiceHost(typeof(JobImplement), new Uri("http://localhost:8080"));
            //
            ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
            behavior.HttpGetEnabled = true;
            host.Description.Behaviors.Add(behavior);
            //
            host.AddServiceEndpoint(typeof(IJob), new BasicHttpBinding(), "Request123");
            host.Open();
            //
            Console.WriteLine("opened");
            Console.ReadLine();
            //
            host.Close();
        }
4

2 に答える 2

3

次のコードにタイプミスがある可能性があります。

static void Main(string[] args)         
{             
    ...
    host.AddServiceEndpoint(typeof(IJob), new BasicHttpBinding(), "Request123");   
    ...
}

タイプ BasicHttpBinding (トランザクションをサポートしないバインディング プロトコル) のエンドポイントを追加しています。

あなたは実際にこれを行うつもりだったと思います:

static void Main(string[] args)         
{             
    WSHttpBinding Basic = new WSHttpBinding();
    Basic.TransactionFlow = true;  
    ...
    host.AddServiceEndpoint(typeof(IJob), Basic, "Request123");   
    ...
}

これにより、トランザクションをサポートするバインディング プロトコルである WSHttpBinding エンドポイントが得られます。

于 2012-04-24T20:38:34.703 に答える
-1

独自のロールバック機能を実装する必要があります。ここでは基本的な方法を説明します。Serviceクラス インターフェイスに属性を追加します[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession, ConcurrencyMode = ConcurrencyMode.Single)]。次に、これらのコードを追加します。

private SqlCommand Command { get; set; }

[OperationContract]
public void BeginTransaction()
{
    this.Command = new SqlCommand();
    string strConnection = @"Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\stavalfi\Desktop\WCF2\ConsoleApplication4\WCF_DB.mdf;Integrated Security=True;Connect Timeout=30;User Instance=True";
    SqlConnection objConnection = new SqlConnection(strConnection);
    objConnection.Open();
    this.Command.Connection = objConnection;
}

[OperationContract]
public void RollBackTransaction()
{
    this.Command.Transaction.Rollback();
}

[OperationContract]
public void CommitTransaction()
{
    this.Command.Transaction.Commit();
}

[OperationContract]
public void CloseConnection()
{
    this.Command.Connection.Close();
    this.Command = null;
}

[OperationBehavior(TransactionScopeRequired = true)]
public void AddEmployee(string Name, string Age)
{
    this.Command.CommandText = "INSERT INTO Employee (Name,Age) " + "VALUES ('" + Name + "' ,'" + Age + "')";
    this.Command.ExecuteNonQuery();
}

次に、次のようにクライアントコードでアクセスできます。

try
{
    proxy.BeginTransaction();
    proxy.AddEmployee("Stav", "20");
    proxy.AddEmployee("Stav123", "Not a Number(-->will do Exception)");
    proxy.CommitTransaction();
}
catch
{
    proxy.RollBackTransaction();
}
finally
{
    proxy.CloseConnection();
}

お役に立てれば。

于 2012-04-23T09:29:58.553 に答える