2011-10-30 7 views
0

私は、Javaのメソッドは、Webサービスに呼び出し、応答に基づいてデータベースに変更を加えています。私の仕事は、複数のユーザーが同時にこのアプリケーションを使用するときに並行性エラーを排除することです。のJavaのWebサービスの同時実行の問題

私は一日中ロックデータベースの様々なタイプを使用しようとしていたが、何も働きました。私は最終的にプロセス要求メソッドでsynchronizedを使用しようとしました。

私の全体のアプリケーションはシングルスレッドです。同期がなぜこれを解決するのですか?

編集:コードを追加しました。

public class ProcessMakePaymentServlet extends HttpServlet { 

    private DbBean db = new DbBean(); 

    protected synchronized void processRequest(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException { 

     // defining variables... 

     try { 

      // initialize parameters for invoking remote method 

      db.connect(); 
      startTransaction(); //autocommit=0; START TRANSACTION; 
      // process debit 
      //this method gets the method using a select...for update. 
      //it then updates it with the new value 
      successfulDebit = debitAccount(userId, amt); 
      if (successfulDebit) { 
       // contact payment gateway by invoking remote pay web service method here. 

       // create new instances of remote Service objects 
       org.tempuri.Service service = new org.tempuri.Service(); 
       org.tempuri.ServiceSoap port = service.getServiceSoap(); 

       // invoke the remote method by calling port.pay(). 
       // port.pay() may time out if the remote service is down and throw an exception 
       successfullyInformedPaymentGateway = port.pay(bankId, bankPwd, payeeId, referenceId, amt); 

       if (successfullyInformedPaymentGateway) { 
        // insert payment record 
        recordPaymentMade(userId, amt, referenceId); 
        //call to the database to record the transaction. Simple update statement. 
        out.println("<br/>-----<br/>"); 
        //getTotalPaymentMade does a select to sum all the payment amounts 
        out.println("Total payment made so far to gateway: " + getTotalPaymentMade()); 
        commitTransaction();// calls COMMIT 
        db.close(); //connection closed. 
       } else { 
        rollbackTransaction();//calls ROLLBACK 
        db.close(); 
        successfulDebit = false; 
        out.println("<br/>-----<br/>"); 
        out.println("Incorrect bank details."); 
       } 
      } else { 
       rollbackTransaction();//calls ROLLBACK 
       db.close(); 
       out.println("<br/>-----<br/>"); 
       out.println("Invalid payment amount."); 
      } 


     } catch (Exception ex) { 
      try { 
       rollbackTransaction();//calls ROLLBACK 
       db.close(); 
      } catch (Exception ex1) { 
      } 
     } 

    } 
+0

だから、あなたのWebサービスへの同時アクセスは、1つのクライアントだけが存在しませんか? – home

+1

「アプリケーション全体がシングルスレッドである」とはどういう意味ですか? –

+0

@Dave Newton私のクラスのどれも、スレッドを拡張するものはありません。 – nknj

答えて

0

が何であるかに依存します。かなり簡略化した例では、私はあなたが私が何を意味するかを取得願っています:

protected void processRequest(HttpServletRequest request, ...) { 

    // defining variables... 
    DbBean db = null; 
    boolean commit = false; 

    try { 
    db = new DbBean(); 
    } catch (SomeException e) { 
    commit = false; 
    } finally{ 
    db.release(commit); /* close database connection => java.sql.Connection#close() */ 
    } 

... 
} 
+0

お返事ありがとうございます。いつかこれを試してください。私はあなたに戻ってきます:) – nknj

2

私の全体のアプリケーションはシングルスレッドです。なぜ同期は を解決しますか?

はありません、それはシングルスレッドではありません。 Webサービスは、クライアント要求を受け取る複数のスレッドによって呼び出されます。

Webサービスメソッドの実装では、複数の要求を受けて、サーブレットの実装と同じすべて同期の問題の世話をする必要があり、注意がスレッドの安全性を確保するために注意する必要があります。

あなたのケースでは、同期を追加することで、Webサービスクライアント要求の同時処理がスレッドの問題により破損せず、クライアント要求(およびDBへのアクセス)がシリアル化されていることを確認しました。

あなたが間違っていることを確認するためのコードは掲載していませんが、ウェブメソッドレベルで同期すると問題が解決されるため、DBレベルで同期を行っていないか、 DBにアクセスするWebサービス層の変数。

synchronizingウェブメソッドでは、コードはスレッドセーフですが、一度に1クライアントを処理するため、パフォーマンスが低下します。

protected void processRequest(HttpServletRequest request, ...) { 

    // defining variables... 
    DbBean db = new DbBean(); 

... 
} 

にもかかわらず、あなたが適切finallyブロック内のすべてのデータベース・リソースをクリーンアップする必要があります

はただ、これが問題の同時実行の問題を解決する必要があり、サーブレットメソッドにprivate DbBean db = new DbBean();を移動し、あなたの要件が

+0

ありがとう!それは私の理解で大いに助けました! – nknj

関連する問題