開発プロセス中に、バグが発生しました。バグの理由は、Springトランザクションがメッセージキューよりも遅れて生産メッセージを送信したため、メッセージキューがメッセージを消費するときに取得されるデータが誤っているためです。この記事では、問題の出現と段階的な解決プロセスを紹介します。
1。発生する問題:
シナリオの復元:インターフェイス内のメソッド、最初に順序ステータスを変更してから、メッセージキューからメッセージを作成します。メッセージキューの消費者は、メッセージの検出順序ステータスを取得し、順序ステータスが変更されていないことがわかります。
コード:
@Service(Orderapi)Public Class OrderApiImplはOrderapi {@Resource MQService MQService; @orderdao orderdao; public void push(string orderid){//注文ステータスを更新すると、以前のステータスは1 updateStatus(orderid、3)でした。 //メッセージmqservice.produce(orderid); } public viod updateStatus(String OrderID、整数ステータス){OrderDao.UpDateStatus(OrderID、Status); }}問題の理由:OrdeAPIのすべてのメソッドにはトランザクションがあり、トランザクションタイプのPropagation_requiredがあるため、すべてのプッシュコードが実行された後、データのプッシュメソッドの操作が送信されます。トランザクションが送信される前に、メッセージキューメッセージが生成されるため、データベースからのメッセージキュークエリで消費される注文のステータスは1になる場合があります。バグをより明確にするために、プッシュメソッドの最後に追加できます。
try {thread.sleep(10000);} catch(arturnedexception e){// dodo auto-enerated catch block e.printstacktrace();}このようにして、消費メッセージが消費されたときに注文ステータスが変更されていないことがわかります。
2。問題の解決策:
解決策:データを更新するときは、更新コードが実行された後、データベースを更新するトランザクションがコミットされたことを確認するために新しいものを作成します。 (メッセージが生成される前にデータベース操作が提出されていることを確認してください)
上記のスキームによると、私が考える最初のことは、UpdateStatusメソッドのトランザクションタイプを直接変更することです。このメソッドのトランザクションタイプをpropagation_requires_newに変更しました(トランザクションが現在存在する場合は、現在のトランザクションを一時停止します)。
しかし、2つの不適切なことがあります。
1.アップデストトゥーストランザクションタイプの強制変更は、他のプロセスに影響を与える可能性があります。
2.機能していないため、UpdateStausメソッドには新しいトランザクションが作成されませんでした。
2番目のポイントの説明:Springは、Beannameautoproxycreatorを介したトランザクションを追加します。これは、Beanオブジェクトにトランザクションを追加するだけです。クラス内のメソッドを呼び出すことは、新しいものの作成をトリガーしません。
上記を試した後、新しいクラスを作成しました。
@service( "orderextapi")パブリッククラスorderextapiimpl {@resource orderapi ordapi; public void updateStatusNewPropagation(String OrderID){Orderapi.updateStatus(orderID); }}UpdateStatusNewPropagationメソッドのトランザクションPropagation_Requires_Newを追加します
このクラスは、OrdapiのUpdatestausメソッドの新しいトランザクションを作成するためだけです。
OK、これまでのところバグは解決されています。
ただし、コードにはまだ問題があります。データベースの操作が送信されており、生産メッセージに例外がある場合、ビジネスロジックにとってはまだ間違っています。したがって、メッセージ生成が完了したかどうかを検出する必要があります。
最終的なOrderapiのコードは次のとおりです。
@Service(Orderapi)Public Class OrderApiImplはOrderapi {@Resource MQService MQService; @Resource OrderDao Orderdao; @resource orderextapiimpl orderextapi; public void push(string orderid){//注文ステータスを更新すると、以前のステータスは1 orderextapi.updatestatusnewpropagation(orderid、3); //メッセージを生成-Produceは例外が発生するかどうかを検出します。 1が返されると、生産メッセージが成功することを意味します。応答応答= mqservice.produce(orderid); if(response.getCode()!= 1){log.info( "メッセージキュー生産メッセージ例外:" + response.getErrormsg())//生成メッセージ例外、ステータスをリセットし、次の再検討orderextapi.updatatatusnewpropagation(orderid、1); }} public Viod updateStatus(String OrderID、整数ステータス){OrderDao.UpDateStatus(OrderID、Status); }}上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。