최근에, 나는 mybatis를 테스트하는 법을 배웠고, 혼자 추가, 삭제, 수정 및 확인하는 데 아무런 문제가 없었습니다. 마지막으로 MVN 테스트를 사용할 때 몇 가지 문제를 발견했습니다.
1. 데이터베이스가 교착 상태가되어 업데이트가 실패했습니다
2. 연결 연결 풀이 사용되어 대기해야하므로 대기 대기를 선택하십시오.
얻다:
1. 탐험 할 용감하고 끈기는 승리입니다. 오류를 처음 보았을 때 오류를 전혀 볼 수 없어서 혼란 스러웠습니다. 프레임 워크 내에서보고 된 오류였습니다. 나는 직접 잠을 자야하는지 주저하고 있었다
결국 거의 12시입니다. 마침내, 나는 문제를 조금 발견했다.
2. 위와 마찬가지로 이해하지 못하는 코드를 파헤 치고 이해하지 못하는 코드를 감히 감히해야합니다.
3. 자격을 갖춘 코더에서 더 멀어지고 멀어지게됩니다. 더 많이 배울수록 허점이 많고 코드는 함정으로 가득 차 있기 때문입니다. 따라서 기록하십시오.
이 두 문제에 대한 다음 기록.
1. MySQL 데이터베이스 교착 상태
여기에서 http://www.cnblogs.com/lin-xuan/p/5280614.html 덕분에 답을 찾았습니다. 여기서 다시 만들겠습니다.
데이터베이스 교착 상태는 트랜잭션 데이터베이스 (예 : SQL Server, MySQL 등)에서 발생하는 일반적인 문제입니다. 데이터베이스 교착 상태 문제가 자주 발생하고 사용자가 작동 할 수 없다면 데이터베이스 교착 문제는 일반적으로 심각하지 않습니다. 응용 프로그램에서 시도해보십시오. 그렇다면 데이터 교착 상태는 어떻게 발생합니까?
Innodb는 공유 잠금 장치 및 Mutex 잠금 (x)으로 나뉘어 진 행 레벨 잠금을 구현합니다.
• 공유 잠금 장치는 트랜잭션 판독 라인에 사용됩니다.
• MUTEX는 트랜잭션 업데이트 또는 한 줄을 삭제하는 데 사용됩니다.
클라이언트 A가 공유 잠금 잠금 장치를 보유하고 MUTEX X를 요청할 때; 동시에 클라이언트 B는 MUTEX X를 보유하고 공유 잠금 S를 요청합니다. 위 상황에서 데이터베이스 교착 상태가 발생합니다. 충분히 명확하지 않은 경우 아래 예제를 참조하십시오.
두 개의 MySQL 클라이언트를 더블 오프닝합니다
클라이언트 A :
거래를 켜고 ID = 12 일 때 공유 잠금을 잠그십시오.
MySQL> 트랜잭션 시작; 쿼리 OK, 0 행에 영향을받습니다 (0.00 초) MySQL> 선택 * 블로그에서 ID = 12 공유 모드에서 12 개 잠금;+----------------+| id | 이름 | author_id |+----+-------+------------- | 12 | 테스트 | 50 |+----+-------+------------------ 세트 1 행 (0.00 초)
클라이언트 B :
트랜잭션을 시작하고 ID = 12를 삭제하려고합니다.
mysql> 트랜잭션 시작; 쿼리 확인, 0 줄은 영향을받습니다 (0.00 sec) mysql> 블로그에서 삭제 된 id = 12;
삭제 작업에는 뮤 테스 (x)가 필요하지만 뮤 테스 X와 공유 잠금 장치는 호환되지 않습니다. 따라서 트랜잭션 삭제는 잠금 요청 큐에 배치되며 클라이언트 B가 차단됩니다.
현재 클라이언트 A는 12를 삭제하려고합니다.
mysql> id = 12; 쿼리 OK, 1 행 영향 (0.00 초)에서 블로그에서 삭제
참조 기사와 달리 삭제는 성공했지만 클라이언트 B는 오류가있었습니다.
오류 1213 (40001) : 잠금을 얻으려고 할 때 교착 상태가 발견되었습니다. 거래를 다시 시작하십시오
그래서 나는 13을 삭제하려고했는데 모두 차단되었습니다.
MyBatis 테스트 코드에서 이전 테스트에는 커밋이 없었기 때문에 교착 상태가 발생했으며 커밋 후 괜찮 았습니다. 여기서는 데이터베이스가 교사에게 반환되었으며 자물쇠와 거래를 다시 검토해야한다고 말하고 싶습니다.
2. MyBatis의 DataSource에 대한 데이터베이스 연결 수
MVN 테스트를 할 때 쿼리 테스트 인쇄 로그를 찾았습니다.
2016-07-21 23 : 43 : 53,356 디버그 [org.apache.ibatis.transaction.jdbc.jdbctransaction]-JDBC 연결 열기
2016-07-21 23 : 43 : 43 : 53,356 디버그 [org.apache.ibatis.datasource.pooled.pooleddatasource]-연결을 위해 20 억 초 정도 기다립니다.
그래서 잠시 기다린 후에 실행이 성공적이었습니다. 소스 코드를 추적하고 이해할 로그를 찾으십시오. 우선, 여기에 사용하는 데이터베이스 연결 구성은 MyBatis 기본값입니다.
<환경 ID = "개발"> <transactionManager type = "jdbc"/> <dataSource type = "pooled"> <property name = "driver"value = "$ {jdbc.driver}"/> <property name = "url"value = "$ {jdbc.url}"/> <property name = "username"value = "$ jdbc.userame}. 이름 = "password"value = "$ {jdbc.password}"/> <속성 이름 = "password"value = "$ {jdbc.password}"/> <datasource> </환경> 데이터베이스 연결 풀의 연결 횟수가 사용되기 전에 2 초를 기다려야합니다. (! state.idleconnections.isempty ()) {// pool은 사용 가능한 ConnectionConn = state.idleConnections.remove (0); if (log.isdebugenabled ()) {log.debug ( "체크 아웃" + conn.getRealhashcode () + ") {// connection이 사용되지 않습니다. (state.ActiveConnections.size () <roommaximumActiveConnection) {// 새 ConnectionConn = New PooledConnection (dataSource.getConnection (), this); if (log.isdebugenabled ()) {log.debug ( "생성 된 연결" + conn.getRealhashCode ()}); ") ConnectionPooledConnection OldestActiveConnection = state.ActiveConnections.get (0); longestcheckouttime = oldestackouttime.getcheckouttime (); if (longestcheckouttime> poolmaximumcheckouttime) {// can can canning connectionstate.claimedOverDueConnectionCount ++; state.AccumulatedCheckOutTimeOfoverDueConnects += longestCheckoutTime += AccumcuMated. longestcheckouttime; state.activeconnections.remove (mardestActiveConnection); if (! oldostActiveConnection.getRealConnection (). getAutoCommit ()) {try {goodStactiveConnection.getRealConnection (). Rollback (). = new PooledConnection (OldestActiveConnection.getRealConnection (), this); oldestActiveConnection.inValidate (); if (log.isdebugenabled ()) {log.debug ( "청구 된 연계 된 연결" + conn.getRealhashCode () + ") else {// 꼭. {state.hadtowaitcount ++; countedwait = true;} if (log.isdebugenabled ()) {log.debug ( "연결을위한" +pooltimetowait +"millionseconds"); System.CurrentTimeMillis () -WT;} Catch (InterruptedException e) {break;}}}}} if (conn! = null) {if (conn.isvalid ()) {if (! conn.getRealConnection (). getAutocommit ()). {conn.getRealConnection (). rollback ();} conn.setConnectionTypecode (assembleconnectiontypecode (dataSource.getUrl (), username, password); conn.setcheckouttimillis (system.currenttimeMillis ()); conn.setLastOussTimEStamp (system.CurrentTimeMillis ()); state.ActiveConnections.add (conn); state.RequestCount ++; state.AccumatedRequestTime+= System.CurrentTimeMillis () -} eloy} elout (log.isdebugenabled ()) {log.debug ( "나쁜 연결 ("+conn.getRealhashCode ()+")가 풀에서 반환되어 다른 연결을 얻습니다. (log.isdebugenabled ()) {log.debug ( "pooleddatasource : 데이터베이스와 잘 연결할 수 없음");}}}}}}연결 횟수가 10 미만인 경우 10 개 이상의 연결을 기다립니다. 그렇지 않으면 오류 가보고됩니다.
위는 MyBatis 업데이트 데이터베이스 교착 상태로 데이터베이스 연결 풀 대기를 얻습니다. 모든 사람에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 모든 사람에게 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!