시간 초과된 DB 조회를 중지하는 방법
6028 단어 timer
하나.문제: 때때로 우리가 실행하는 DB 조회(예를 들어 일부 조회의 저장 프로세스)는 시간이 너무 길다. 우리의 코드가 논리적으로 이렇게 오래 기다리고 싶지 않을 때 어떻게 삭제합니까?
둘.생각: 먼저 "select connection Id ()"를 사용한 다음 "kill query id"문구를 통해 대응하는 DB 프로세스를 삭제합니다.나중에 JdbcTemplate에서CallableStatement의cancel()이 저장 프로세스의 호출을 끄는 것을 발견했다.그러면 우리는 Timer와 결합하여 시간을 계산할 수 있으며, N분이 넘으면 cancel () 을 실행하면 된다.
셋.코드:
1.task 정의: (connection Id에 맞추어 추적할 수 있습니다. 논리적으로는 사용되지 않았지만)
public class CustomTimeTask extends TimerTask {
private static final Logger logger = LoggerFactory.getLogger(CustomTimeTask.class);
CallableStatement cs ;
int id;
public CustomTimeTask(CallableStatement cs, int id) {
super();
this.cs = cs;
this.id = id;
}
@Override
public void run() {
try {
logger.info("[Timeout]TimeTask try to cancel the long time procedure query. Connection ID is [{}]", id);
cs.cancel();
} catch (Exception e) {
logger.error("[Timeout]TimeTask fail to cancel the long time procedure query. Please check the if the query has been stopped in database. "
+ "The connection ID is [{}]", id);
}
}
}
2. 실행:
logger.debug("-----------Start to call CSV store procedure------------");
Connection conn = null;
CallableStatement cs = null;
ResultSet rs = null;
Timer timer = null;
boolean isQuery = false;
......
try{
conn = jdbcTemplate.getDataSource().getConnection();
cs = conn.prepareCall(foo);
....
isQuery = true;
int queryTimeoutMins = SystemConfig.getQueryTimeout();
if(queryTimeoutMins>0) {
logger.debug("Execute the statemnet to call procedure to connection ID [{}]. "
+ "And start the timer to cancel the timeout query. Timeout setting [{} minutes]"
,conID,queryTimeoutMins);
CustomTimeTask customTimeTask = new CustomTimeTask(cs, conID);
timer = new Timer();
timer.schedule(customTimeTask, queryTimeoutMins * 60 * 1000);
}else {
logger.debug("Execute the statemnet to call procedure to gen CSV record to connection ID [{}]. "
+ "But not start the timer to cancel the timeout query because timeout setting is [{} minutes]"
,conID,queryTimeoutMins);
}
cs.execute();
if(timer != null) {
logger.debug("The query for connection ID [{}] is completed. "
+ "Cancel the timer and begin to get the resultSet. ",conID);
timer.cancel();
timer.purge();
}else {
logger.debug("The query for connection ID [{}] is completed. Begin to get the resultSet.",conID);
}
isQuery = false;
rs = cs.getResultSet();
.........
...........
rs.close();
}catch (DataAccessException e) {
dbLogger.error("DB is down. Exception is [{}]", e.getMessage());
try {
if(isQuery && cs!=null && !cs.isClosed()) {
logger.info("Program has begun the query. Try to cancel the procedure query for connection ID [{}]"
, conID);
cs.cancel();
}
} catch (MySQLStatementCancelledException e1) {
logger.info("Successfully cancel the procedure query for connection ID [{}]"
, conID);
if(timer != null) {
timer.cancel();
timer.purge();
}
isQuery = false;
} catch (Exception e1) {
logger.error("-- Error occur when try to cancel the query for connection ID[{}]. "
+ "Exception is [{}].",conID, e.getMessage());
}
throw e;
} catch (MySQLStatementCancelledException e) {
logger.info("Successfully cancel the procedure query for connection ID [{}]"
, conID);
if(timer != null) {
timer.cancel();
timer.purge();
}
isQuery = false;
return null;
}catch (Exception e) {
logger.error("-- Error occur, exception is [{}]", e.getMessage());
logger.error("DB: error:", e);
try {
if(isQuery && cs!=null && !cs.isClosed()) {
logger.info("Program has begun the query. Try to cancel the procedure query for connection ID [{}]"
, conID);
cs.cancel();
}
} catch (MySQLStatementCancelledException e1) {
logger.info("Successfully cancel the procedure query for connection ID [{}]"
, conID);
if(timer != null) {
timer.cancel();
timer.purge();
}
isQuery = false;
} catch (Exception e1) {
logger.error("-- Error occur when try to cancel the query for connection ID[{}]. "
+ "Exception is [{}].",conID, e.getMessage());
}
return null;
}finally {
try {
if (rs != null)
rs.close();
if (cs != null)
cs.close();
if (conn != null) {
conn.close();
}
} catch (Exception e) {
logger.error("Error occurs when close the connection to database. Error:", e);
return null;
}
}
logger.debug("-----------End to call store procedure------------");
return resultMap;
}
몇 가지 주의할 점이 있습니다. 생략된 부분은 정상적인 cs 실행 저장 프로세스의 처리입니다.그러나 timer에 대해 판단해야 한다.
1.조회가 끝났으면 schedule을 기다릴 필요가 없습니다.timer를 취소해야 합니다
2. DB가 잘못되면 조회 여부를 판단하고 cs가close인지 확인하십시오. 그렇지 않으면 cs를 호출해야 합니다.cancel () 로 끝내기
3. 동시에 cs를 주의한다.cancel () 후 timer가 끝났는지 여부
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
자바스크립트로 타이머 만들기JavaScript와 HTML만 사용하여 간단한 타이머를 만들어 보겠습니다. 먼저 인터페이스를 만들고 HTML만 사용하여 간단한 작업을 수행합니다. HTML 구조에서 시간 정보를 표시하기 위해 일부span가 생성되었...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.