1

私はこのGUIDを使用しました:http://www.c-sharpcorner.com/uploadfile/shivprasadk/wcf-faq-part-5-transactions/ なぜロールバックしませんか?わかりません!WCF TransactionScopeはロールバックしません

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

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

私は年齢パラメータに番号を送信didntのが、トランザクションが情報ように、最初の行をロールバックdoesntのbecouse次の行スロー例外:STAV、 20まだ私のDBにexsist!

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

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

AddEmployeeメソッドの実装方法を追加しますか?それは実際にトランザクションを尊重しますか? – user957902

+0

トピックを実装で更新しました。他に何か? –

+0

どのバインディングを使用していますか?すべてのバインディングがトランザクションをサポートするわけではありません。 – user957902

答えて

2

それはあなたがここにあなたのコード内での可能なタイプミス持つようになっています

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

をあなたがタイプBasicHttpBindingのエンドポイントを追加している - トランザクションをサポートしていないバインディングプロトコルを。

私はあなたが実際にこれを実行することを意図していることを考えています:あなたのWSHttpBindingエンドポイント与えるだろう

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

- トランザクションをサポートしないバインディングのプロトコルを。

+0

OMGは本当にありがとう!私はそれを愚かな私はBasicHttpBidingで削除することを忘れて2つの設定ファイルを持っていた私は死ぬことはできません。 –

0

あなたがあなた自身のロールバック機能を実装する必要があります。これを行うための基本的な方法があります。 サービスクラスのインターフェイスに[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(); 
} 

は、この情報がお役に立てば幸いです。

+0

すべての記事では、クライアントはtransactionScopeで構成されていました(サービスが1つ以上の場合は、1つのサービスで構成される単純な例を作成していましたが、次の例ではサービスを追加します)私の目標を達成していれば無益です.btw、それは何ですか?[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession、ConcurrencyMode = ConcurrencyMode.Single)]? –

+0

@StavAlfi [それは可能だと思います。](http://stackoverflow.com/a/8982167/1115937)これを行うには少なくともトランザクション型を渡す必要がありますが、それは直列化できません。また、必要なものを得るために、すべてのクエリで単一の接続が必要です。 –

+0

私はそれをすべてやったので、何が間違っていますか? –

関連する問題