最近、私はMyBatisのテストを学びましたが、単独で追加、削除、変更、チェックすることに問題はありませんでした。最後に、MVNテストを使用する際にいくつかの問題が発見されました。
1.データベースがデッドロックされているため、更新が失敗しました
2.接続接続プールが使い果たされ、待つ必要があるため、待機を選択してください
得る:
1。勇敢に探検してください。そして、粘り強さは勝利です。エラーを初めて見たとき、エラーがまったく見えなかったので混乱しました。フレームワーク内で報告されたエラーでした。私は直接眠るかどうかをためらいました
結局のところ、それはほぼ12時です。最後に、私は問題を少し見つけました。
2。上記と同じように、あなたが理解していないコードを掘り下げ、あなたが理解していないコードを勉強することを敢えてしなければなりません。
3.資格のあるコーダーから遠く離れているので、学習すればするほど抜け穴を感じ、コードが落とし穴に満ちているからです。したがって、必ず記録してください。
これら2つの問題の次の記録。
1。MySQLデータベースデッドロック
ここで、http://www.cnblogs.com/lin-xuan/p/5280614.htmlのおかげで、答えを見つけました。ここで、私はそれを再現します:
データベースデッドロックは、トランザクションデータベース(SQL Server、MySQLなど)で発生する一般的な問題です。データベースのデッドロックの問題が頻繁に発生し、ユーザーが動作できない場合を除き、データベースのデッドロックの問題は一般に深刻ではありません。アプリケーションを試してみてください。では、データデッドロックはどのように発生しますか?
INNODBは、共有ロックとミューテックスロック(x)に分割された行レベルロックを実装します。
•共有ロックは、トランザクション読み取りラインに使用されます。
•Mutexは、トランザクションの更新または1行の削除に使用されます。
クライアントAが共有ロックsを保持し、Mutex xを要求する場合。同時に、クライアントBはMutex Xを保持し、上記の状況で共有ロックSを要求し、データベースのデッドロックが発生します。十分に明確でない場合は、以下の例をご覧ください。
2つのMySQLクライアントを二重に開いています
クライアントA:
ID = 12の場合、トランザクションをオンにし、共有ロックsをロックします。
mysql>トランザクションを開始;クエリOK、0行の影響(0.00秒)mysql> select * from blog = 12 lock in shareモード;+----+-------+----------+| ID |名前|著者_id |+----+-------+----------+| 12 | testa | 50 |+----+-------+----------+1行の列(0.00秒)
クライアントB:
トランザクションを開始し、id = 12を削除してみてください:
mysql> start transaction; query ok、0行の影響(0.00秒)mysql> blog = 12から削除します。
削除操作にはMutex(x)が必要ですが、Mutex xと共有ロックsは互換性がありません。したがって、削除トランザクションはロックリクエストキューに配置され、クライアントBがブロックされます。
現時点では、クライアントAも12を削除したいと考えています。
mysql>ブログから削除id = 12; query ok、1行の影響(0.00秒)
参照記事とは異なり、削除は成功しましたが、クライアントBにはエラーがありました。
エラー1213(40001):ロックを取得しようとしたときにデッドロックが見つかりました。トランザクションを再起動してみてください
それで、私は13を削除しようとしました、そしてそれはすべてブロックされました:
私のMyBatisテストコードでは、以前のテストにはコミットがなかったため、デッドロックを引き起こし、コミット後も問題ありませんでした。ここでは、データベースが教師に返され、ロックとトランザクションを再度レビューする必要があると言いたいと思います。
2。MyBatisのDataSourceへのデータベース接続の数
MVNテストで、クエリテスト印刷ログを見つけました:
2016-07-21 23:43:53,356 Debug [org.apache.ibatis.transaction.jdbc.jdbctransaction] - JDBC接続を開く
2016-07-21 23:43:53,356 Debug [org.apache.ibatis.datasource.pooled.pooleddatasource] - 接続を200万秒間待っています。
したがって、しばらく待った後、実行は成功しました。ソースコードを追跡し、このログを見つけて理解してください。まず、ここで使用するデータベース接続構成はMyBatisデフォルトです。
<環境ID = "Development"> <TransactionManager Type = "JDBC"/> <DataSource Type = "Pooled"> <プロパティ名= "Driver" value = "$ {jdbc.driver}"/> <プロパティ名= "url" value = "$ {jdbc.url}"/> <Property name = "usermame" $ "" $ "us namame} name = "password" value = "$ {jdbc.password}"/> <プロパティ名= "password" value = "$ {jdbc.password}"/> <dataSource> </環境>データベース接続プールの接続数が使用された後、2秒前に待つ必要があります。 (!state.idleconnections.isempty()){//プールにはconnectionconn = state.idleconnections.remove(0); if(log.isdebugenabled()){log.debug( "checked connection" + conn.getRealHashCode() + "pool。 (state.activeconnections.size()<poolmaximumactiveconnections){// new connectionconn = new PooledConnection(dataSource.getConnection()、this); if(log.isdebugenabled(){log.debug( "recumition connection" + conn.getRealhashcode() + " ConnectionPooledConnection Oldestactiveconnection = state.activeconnections.get(0); longestCheckoutTime = oldestactiveconnection.getCheckouttime(); if(longestcheckouttime> poolmaximumcheckouttime){// connectionState.claidedoverdueconnectioncount ++; state.accumulatedcheckouttimeofofofofovedueconnections += longestcheckouttime; longestcheckouttime; state.activeconnections.remove(oldestactiveconnection); if(!oldestactiveconnection.getrealConnection()。 } conn = new PooledConnection(oldestactiveconnection.getRealConnection()、this); oldestactiveconnection.invalidate(); if(log.isdebugenabled()){log.debug( "charesed connection" + conn.getRealHashCode() {state.hadtowaitcount ++; countedwait = true;} if(log.isdebugenabled()){log.debug( "" +pooltimetowait +"neconeconds for connection");} long wt = system.currenttimemillis(); state.wait seatt(pooltimetowait sed); System.CurrentTimemillis()-WT;} catch(arternedexception e){break;}}}}}}}}}} {if(conn.isvalid()){if(!conn.getRealConnection()。getAutoCommit())) {conn.getRealConnection()。rollback();} conn.setConnectionTypeCode(andiceSource.getUrl()、username、パスワード)); conn.setcheckouttimestamp(system.currenttimemillis()); conn.setLastusedTimeStamp(System.CurrentTimemillis()); state.activeconnections.add(conn); state.RequestCount ++; state.AccumulateRrequesttime+= System.CurrentTimemillis+= Currenttimemillis+ (log.isdebugenabled()){log.debug( "bad connection("+conn.getRealHashCode()+")はプールから返され、別の接続を取得しました。} state.badconnectionCount ++; (log.isdebugenabled()){log.debug( "pooleddatasource:データベースへの適切な接続を取得できませんでした。");}}}}}}接続の数が10未満の場合、10を超える接続が待機します。そうしないと、エラーが報告されます。
上記は、データベース接続プールを取得するためのMyBatis Update Database Deadlockです。私はそれが誰にでも役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は、すべての人に時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!