JDBCRecoveryLog.java の 61 行で定義されています。
Public メソッド | |
JDBCRecoveryLog (String driverName, String driverClassName, String url, String login, String password, int requestTimeout) | |
void | checkRecoveryLogTables () |
long | getLastTransactionId () throws SQLException |
void | setLogTableCreateStatement (String tableName, String idType, String vloginType, String sqlType, String transactionIdType, String extraStatement) |
void | setCheckpointTableCreateStatement (String tableName, String nameType, String requestIdType, String extraStatement) |
void | setBackendTableCreateStatement (String tableName, String checkpointNameType, String backendNameType, String databaseNameType, String extraStatement) |
void | logRequest (AbstractWriteRequest request) throws SQLException |
void | logRequest (StoredProcedure proc, boolean isRead) throws SQLException |
void | begin (TransactionMarkerMetaData tm) throws SQLException |
void | commit (TransactionMarkerMetaData tm) throws SQLException |
void | rollback (TransactionMarkerMetaData tm) throws SQLException |
void | storeCheckpoint (String checkpointName) throws SQLException |
void | storeCheckpoint (String checkpointName, long requestId) throws SQLException |
long | getCheckpointRequestId (String checkpointName) throws SQLException |
RecoveryTask | recoverNextRequest (long previousRequestId) throws SQLException |
void | cleanRecoveryLog () throws SQLException |
void | removeCheckpoint (String checkpointName) throws SQLException |
ArrayList | getCheckpointNames () throws SQLException |
void | storeBackendCheckpoint (String databaseName, String backendName, String checkpoint) throws SQLException |
String | getBackendCheckpoint (String databaseName, String backendName) |
String | getXmlImpl () |
synchronized void | beginRecovery () |
synchronized void | endRecovery () |
synchronized boolean | isRecovering () |
String | getXml () |
スタティック変数 | |
Trace | logger |
Private メソッド | |
synchronized long | incrementLogTableId () |
void | intializeDatabase () throws SQLException |
void | connectToDatabase () throws SQLException |
boolean | validCheckpointName (String checkpointName) throws SQLException |
void | waitForTransactionsEnd (boolean forceRollback) |
Private 変数 | |
String | driver |
String | driverName |
String | url |
String | login |
String | password |
String | logTable |
String | logTableCreateStatement |
String | idType |
String | vloginType |
String | sqlType |
String | transactionIdType |
String | logextraStatement |
String | checkpointTable |
String | checkpointTableCreateStatement |
String | backendTableCreateStatement |
String | backendTableName |
String | nameType |
String | requestIdType |
String | checkextraStatement |
Connection | connection |
PreparedStatement | pstmt |
long | logTableId = 0 |
int | timeout |
JDBCLoggerThread | loggerThread |
|
Creates a new
JDBCRecoveryLog.java の 129 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.connectToDatabase().
00131 { 00132 this.driverName = driverName; 00133 this.driver = driverClassName; 00134 this.url = url; 00135 this.login = login; 00136 this.password = password; 00137 this.timeout = requestTimeout; 00138 00139 // Connect to the database 00140 try 00141 { 00142 connectToDatabase(); 00143 } 00144 catch (SQLException e) 00145 { 00146 throw new RuntimeException("Unable to connect to the database: " + e); 00147 } 00148 00149 // Logger thread will be created in checkRecoveryLogTables() 00150 // after database has been initialized 00151 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 496 行で定義されています。
00497 { 00498 // Store the begin in the database 00499 loggerThread.log(incrementLogTableId(), login, "begin", tm 00500 .getTransactionId(), false); 00501 } |
|
Notify the recovery log that a recovery process has started. AbstractRecoveryLog.java の 174 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLog.recoveringNb.
00176 { 00177 recoveringNb++; 00178 } |
|
Checks if the recovery log and checkpoint tables exist, and create them if they do not exist. This method also starts the logger thread. JDBCRecoveryLog.java の 157 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.intializeDatabase(), org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.loggerThread, と org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.logTable.
00158 { 00159 try 00160 { 00161 intializeDatabase(); 00162 pstmt = connection.prepareStatement("INSERT INTO " + logTable 00163 + " VALUES(?,?,?,?)"); 00164 } 00165 catch (SQLException e) 00166 { 00167 throw new RuntimeException("Unable to initialize the database: " + e); 00168 } 00169 00170 PreparedStatement removeBeginStatement = null; 00171 try 00172 { 00173 removeBeginStatement = connection.prepareStatement("DELETE FROM " 00174 + logTable + " WHERE transaction_id=? AND sql LIKE ?"); 00175 removeBeginStatement.setString(2, "begin"); 00176 } 00177 catch (SQLException e) 00178 { 00179 throw new RuntimeException("Failed to create removed statement (" + e 00180 + ")"); 00181 } 00182 00183 // Start the logger thread 00184 loggerThread = new JDBCLoggerThread(pstmt, removeBeginStatement, logger); 00185 loggerThread.start(); 00186 } |
|
Removes all rollbacked transaction from the recovery log and deletes all begin/commit statements for completed transactions.
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 916 行で定義されています。
00917 { 00918 // Remove the begin statements from the database 00919 PreparedStatement stmt = null; 00920 try 00921 { 00922 stmt = connection.prepareStatement("DELETE FROM " + logTable 00923 + " WHERE sql LIKE ?"); 00924 stmt.setString(1, "begin"); 00925 stmt.executeUpdate(); 00926 stmt.close(); 00927 } 00928 catch (SQLException e) 00929 { 00930 try 00931 { 00932 if (stmt != null) 00933 stmt.close(); 00934 } 00935 catch (Exception ignore) 00936 { 00937 } 00938 throw new SQLException("Unable to remove begin statements : " + e); 00939 } 00940 // Remove the commit statements from the database 00941 try 00942 { 00943 stmt = connection.prepareStatement("DELETE FROM " + logTable 00944 + " WHERE sql LIKE ?"); 00945 stmt.setString(1, "commit"); 00946 stmt.executeUpdate(); 00947 stmt.close(); 00948 } 00949 catch (SQLException e) 00950 { 00951 try 00952 { 00953 if (stmt != null) 00954 stmt.close(); 00955 } 00956 catch (Exception ignore) 00957 { 00958 } 00959 throw new SQLException("Unable to remove commit statements : " + e); 00960 } 00961 00962 // Remove the rollback statements and 00963 //associated requests from the database 00964 ResultSet rs = null; 00965 try 00966 { 00967 // Get the list of transaction ids on which a rollback occurred 00968 stmt = connection.prepareStatement("SELECT transaction_id FROM " 00969 + logTable + " WHERE sql LIKE ?"); 00970 stmt.setString(1, "rollback"); 00971 rs = stmt.executeQuery(); 00972 } 00973 catch (SQLException e) 00974 { 00975 try 00976 { 00977 if (stmt != null) 00978 stmt.close(); 00979 } 00980 catch (Exception ignore) 00981 { 00982 } 00983 throw new SQLException("Unable get rollback statements : " + e); 00984 } 00985 PreparedStatement p = null; 00986 long transactionId = -1; 00987 try 00988 { 00989 // remove the rollbacked transaction from the database 00990 while (rs.next()) 00991 { 00992 transactionId = rs.getLong("transaction_Id"); 00993 p = connection.prepareStatement("DELETE FROM " + logTable 00994 + " WHERE transaction_id=?"); 00995 p.setLong(1, transactionId); 00996 p.executeUpdate(); 00997 p.close(); 00998 } 00999 stmt.close(); 01000 } 01001 catch (SQLException e) 01002 { 01003 try 01004 { 01005 if (stmt != null) 01006 stmt.close(); 01007 if (p != null) 01008 p.close(); 01009 } 01010 catch (Exception ignore) 01011 { 01012 } 01013 throw new SQLException(Translate.get( 01014 "recovery.jdbc.transaction.remove.failed", new String[]{ 01015 String.valueOf(transactionId), e.getMessage()})); 01016 } 01017 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 506 行で定義されています。
00507 { 00508 if (isRecovering()) 00509 { 00510 // Some backends started a recovery process, log the commit 00511 loggerThread.log(incrementLogTableId(), login, "commit", tm 00512 .getTransactionId(), false); 00513 } 00514 else 00515 { // The transaction succeeded 00516 // Remove the begin with this tranactionId from the database 00517 loggerThread.log(incrementLogTableId(), login, "c", 00518 tm.getTransactionId(), false); 00519 } 00520 } |
|
Gets a connection to the database.
JDBCRecoveryLog.java の 449 行で定義されています。 参照元 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.JDBCRecoveryLog().
00450 { 00451 // Get a connection 00452 try 00453 { 00454 if (logger.isDebugEnabled()) 00455 logger.debug(Translate.get("recovery.jdbc.connect", new String[]{url, 00456 login})); 00457 connection = DriverManager.getConnection(url, login, password, 00458 driverName, driver); 00459 } 00460 catch (SQLException e) 00461 { 00462 throw new SQLException(Translate.get("recovery.jdbc.connect", e)); 00463 } 00464 } |
|
Notify the recovery log that a recovery process has finished. If this is the last recovery process to finish, the cleanRecoveryLog method is called
AbstractRecoveryLog.java の 186 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLog.cleanRecoveryLog(), org.objectweb.cjdbc.common.log.Trace.error(), と org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLog.recoveringNb.
00187 { 00188 recoveringNb--; 00189 if (recoveringNb == 0) 00190 { 00191 try 00192 { 00193 cleanRecoveryLog(); 00194 } 00195 catch (SQLException e) 00196 { 00197 logger.error(Translate.get("recovery.cleaning.failed", e)); 00198 } 00199 } 00200 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 1163 行で定義されています。
01164 { 01165 PreparedStatement stmt = null; 01166 String checkpoint = null; 01167 try 01168 { 01169 // 1. Get the reference point to delete 01170 stmt = connection.prepareStatement("SELECT checkpointName from " 01171 + backendTableName 01172 + " WHERE backendName LIKE ? and databaseName LIKE ?"); 01173 stmt.setString(1, backendName); 01174 stmt.setString(2, databaseName); 01175 ResultSet rs = stmt.executeQuery(); 01176 01177 if (rs.next()) 01178 { 01179 checkpoint = rs.getString("checkpointName"); 01180 } 01181 stmt.close(); 01182 } 01183 catch (SQLException e) 01184 { 01185 try 01186 { 01187 if (stmt != null) 01188 stmt.close(); 01189 } 01190 catch (Exception ignore) 01191 { 01192 } 01193 } 01194 return checkpoint; 01195 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 1075 行で定義されています。
01076 { 01077 PreparedStatement stmt = null; 01078 01079 // Wait for transaction to finish 01080 waitForTransactionsEnd(true); 01081 01082 try 01083 { 01084 stmt = connection.prepareStatement("SELECT name from " + checkpointTable); 01085 ResultSet rs = stmt.executeQuery(); 01086 ArrayList list = new ArrayList(); 01087 while (rs.next()) 01088 { 01089 list.add(rs.getString("name")); 01090 } 01091 return list; 01092 } 01093 catch (Exception e) 01094 { 01095 throw new SQLException(Translate.get( 01096 "recovery.jdbc.checkpoint.list.failed", e)); 01097 } 01098 01099 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 688 行で定義されています。
00689 { 00690 long requestId = -1; 00691 PreparedStatement stmt = null; 00692 try 00693 { 00694 ResultSet rs = null; 00695 stmt = connection.prepareStatement("SELECT request_id FROM " 00696 + checkpointTable + " WHERE name LIKE ?"); 00697 stmt.setString(1, checkpointName); 00698 rs = stmt.executeQuery(); 00699 00700 if (rs.next()) 00701 { 00702 requestId = rs.getInt("request_id"); 00703 } 00704 stmt.close(); 00705 } 00706 catch (SQLException e) 00707 { 00708 try 00709 { 00710 if (stmt != null) 00711 stmt.close(); 00712 } 00713 catch (Exception ignore) 00714 { 00715 } 00716 throw new SQLException(Translate.get( 00717 "recovery.jdbc.checkpoint.not.found", new String[]{checkpointName, 00718 e.getMessage()})); 00719 } 00720 return requestId; 00721 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 191 行で定義されています。 参照先 java.sql.Statement.executeQuery(), と org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.logTable.
00192 { 00193 Statement stmt = connection.createStatement(); 00194 ResultSet rs = stmt.executeQuery("select max(transaction_id) from " 00195 + logTable); 00196 if (rs.next()) 00197 return rs.getInt(1); 00198 else 00199 return 0; 00200 } |
|
Get xml information of the current recovery load in the system.
AbstractRecoveryLog.java の 225 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLog.getXmlImpl().
00227 { 00228 StringBuffer info = new StringBuffer(); 00229 info.append("<" + DatabasesXmlTags.ELT_RecoveryLog + ">"); 00230 info.append(getXmlImpl()); 00231 info.append("</" + DatabasesXmlTags.ELT_RecoveryLog + ">"); 00232 return info.toString(); 00233 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 1200 行で定義されています。
01201 { 01202 StringBuffer info = new StringBuffer(); 01203 info.append("<" + DatabasesXmlTags.ELT_JDBCRecoveryLog + " " 01204 + DatabasesXmlTags.ATT_driver + "=\"" + driver + "\" " 01205 + DatabasesXmlTags.ATT_url + "=\"" + url + "\" " 01206 + DatabasesXmlTags.ATT_login + "=\"" + login + "\" " 01207 + DatabasesXmlTags.ATT_password + "=\"" + password + "\" " 01208 + DatabasesXmlTags.ATT_requestTimeout + "=\"" + timeout + "\">"); 01209 // Recovery Log table 01210 info.append("<" + DatabasesXmlTags.ELT_RecoveryLogTable + " " 01211 + DatabasesXmlTags.ATT_tableName + "=\"" + logTable + "\"" + " " 01212 + DatabasesXmlTags.ATT_idColumnType + "=\"" + idType + "\"" + " " 01213 + DatabasesXmlTags.ATT_vloginColumnType + "=\"" + vloginType + "\"" 01214 + " " + DatabasesXmlTags.ATT_sqlColumnType + "=\"" + sqlType + "\"" 01215 + " " + DatabasesXmlTags.ATT_transactionIdColumnType + "=\"" 01216 + transactionIdType + "\"" + " " 01217 + DatabasesXmlTags.ATT_extraStatementDefinition + "=\"" 01218 + logextraStatement + "\"/>"); 01219 // Checkpoint table 01220 info.append("<" + DatabasesXmlTags.ELT_CheckpointTable + " " 01221 + DatabasesXmlTags.ATT_tableName + "=\"" + checkpointTable + "\"" + " " 01222 + DatabasesXmlTags.ATT_checkpointNameColumnType + "=\"" + nameType 01223 + "\"" + " " + DatabasesXmlTags.ATT_requestIdColumnType + "=\"" 01224 + requestIdType + "\"" + " " 01225 + DatabasesXmlTags.ATT_extraStatementDefinition + "=\"" 01226 + checkextraStatement + "\"" + "/>"); 01227 info.append("</" + DatabasesXmlTags.ELT_JDBCRecoveryLog + ">"); 01228 return info.toString(); 01229 } |
|
Increments the value of logTableId. JDBCRecoveryLog.java の 289 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.logTableId.
00290 { 00291 logTableId++; 00292 return logTableId; 00293 } |
|
Checks if the tables (log and checkpoint) already exist, and create them if needed. JDBCRecoveryLog.java の 299 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.backendTableName, org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.checkpointTable, org.objectweb.cjdbc.common.log.Trace.debug(), org.objectweb.cjdbc.common.log.Trace.isDebugEnabled(), org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.logTable, org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.logTableId, と org.objectweb.cjdbc.common.log.Trace.warn(). 参照元 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.checkRecoveryLogTables().
00300 { 00301 boolean createLogTable = true; 00302 boolean createCheckpointTable = true; 00303 boolean createBackendTable = true; 00304 // Check if tables exist 00305 try 00306 { 00307 // Get DatabaseMetaData 00308 DatabaseMetaData metaData = connection.getMetaData(); 00309 00310 // Get a description of tables matching the catalog, schema, table name 00311 // and type. 00312 // Sending in null for catalog and schema drop them from the selection 00313 // criteria. Replace the last argument in the getTables method with 00314 // types below to obtain only database tables. (Sending in null 00315 // retrieves all types). 00316 String[] types = {"TABLE", "VIEW"}; 00317 ResultSet rs = metaData.getTables(null, null, "%", types); 00318 00319 // Get tables metadata 00320 String tableName; 00321 while (rs.next()) 00322 { 00323 // 1 is table catalog, 2 is table schema, 3 is table name, 4 is type 00324 tableName = rs.getString(3); 00325 if (logger.isDebugEnabled()) 00326 logger.debug(Translate.get("recovery.jdbc.table.found", tableName)); 00327 if (tableName.equalsIgnoreCase(logTable)) 00328 { 00329 if (!tableName.equals(logTable)) 00330 logger.warn(Translate.get("recovery.jdbc.table.case.mismatch", 00331 new String[]{logTable, tableName})); 00332 createLogTable = false; 00333 // initialize logTableId 00334 PreparedStatement p = null; 00335 try 00336 { 00337 ResultSet result = null; 00338 p = connection.prepareStatement("SELECT MAX(id) AS max_id FROM " 00339 + logTable); 00340 result = p.executeQuery(); 00341 if (result.next()) 00342 logTableId = result.getInt("max_id"); 00343 else 00344 logTableId = 0; 00345 p.close(); 00346 } 00347 catch (SQLException e) 00348 { 00349 try 00350 { 00351 if (p != null) 00352 p.close(); 00353 } 00354 catch (Exception ignore) 00355 { 00356 } 00357 throw new RuntimeException(Translate.get( 00358 "recovery.jdbc.logtable.getvalue.failed", e)); 00359 } 00360 00361 } 00362 if (tableName.equalsIgnoreCase(checkpointTable)) 00363 { 00364 if (!tableName.equals(logTable)) 00365 logger.warn(Translate.get( 00366 "recovery.jdbc.checkpointtable.case.mismatch", new String[]{ 00367 checkpointTable, tableName})); 00368 createCheckpointTable = false; 00369 } 00370 if (tableName.equalsIgnoreCase(backendTableName)) 00371 { 00372 if (!tableName.equals(backendTableName)) 00373 logger.warn(Translate.get( 00374 "recovery.jdbc.backendtable.case.mismatch", new String[]{ 00375 backendTableName, tableName})); 00376 createBackendTable = false; 00377 } 00378 } 00379 } 00380 catch (SQLException e) 00381 { 00382 logger.error(Translate.get("recovery.jdbc.table.no.description"), e); 00383 throw e; 00384 } 00385 00386 // Create the missing tables 00387 Statement stmt = null; 00388 if (createLogTable) 00389 { 00390 if (logger.isInfoEnabled()) 00391 logger.info(Translate.get("recovery.jdbc.logtable.create", logTable)); 00392 try 00393 { 00394 stmt = connection.createStatement(); 00395 stmt.executeUpdate(logTableCreateStatement); 00396 stmt.close(); 00397 } 00398 catch (SQLException e) 00399 { 00400 throw new SQLException(Translate.get( 00401 "recovery.jdbc.logtable.create.failed", new String[]{logTable, 00402 e.getMessage()})); 00403 } 00404 } 00405 if (createCheckpointTable) 00406 { 00407 if (logger.isInfoEnabled()) 00408 logger.info(Translate.get("recovery.jdbc.checkpointtable.create", 00409 checkpointTable)); 00410 try 00411 { 00412 stmt = connection.createStatement(); 00413 stmt.executeUpdate(checkpointTableCreateStatement); 00414 stmt.close(); 00415 } 00416 catch (SQLException e) 00417 { 00418 throw new SQLException(Translate.get( 00419 "recovery.jdbc.checkpointtable.create.failed", new String[]{ 00420 logTable, e.getMessage()})); 00421 } 00422 } 00423 if (createBackendTable) 00424 { 00425 if (logger.isInfoEnabled()) 00426 logger.info(Translate.get("recovery.jdbc.backendtable.create", 00427 backendTableName)); 00428 try 00429 { 00430 stmt = connection.createStatement(); 00431 stmt.executeUpdate(backendTableCreateStatement); 00432 stmt.close(); 00433 } 00434 catch (SQLException e) 00435 { 00436 throw new SQLException(Translate.get( 00437 "recovery.jdbc.backendtable.create.failed", new String[]{logTable, 00438 e.getMessage()})); 00439 } 00440 } 00441 00442 } |
|
Returns
AbstractRecoveryLog.java の 208 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLog.recoveringNb.
00209 {
00210 return recoveringNb > 0;
00211 }
|
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 478 行で定義されています。
00480 { 00481 if (isRead) 00482 loggerThread.log(incrementLogTableId(), proc.getLogin(), proc.getSQL(), 00483 proc.getTransactionId(), proc.getEscapeProcessing()); 00484 else 00485 { // Reverse the first bracket so that we can identify a write call 00486 StringBuffer writeCall = new StringBuffer(proc.getSQL()); 00487 writeCall.setCharAt(0, '}'); 00488 loggerThread.log(incrementLogTableId(), proc.getLogin(), writeCall 00489 .toString(), proc.getTransactionId(), proc.getEscapeProcessing()); 00490 } 00491 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 469 行で定義されています。
00470 { 00471 loggerThread.log(incrementLogTableId(), request.getLogin(), request 00472 .getSQL(), request.getTransactionId(), request.getEscapeProcessing()); 00473 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 726 行で定義されています。 参照先 org.objectweb.cjdbc.common.sql.AbstractRequest.setIsAutoCommit(), org.objectweb.cjdbc.common.sql.AbstractRequest.setLogin(), と org.objectweb.cjdbc.common.sql.AbstractRequest.setTransactionId().
00728 { 00729 RecoveryTask task = null; 00730 00731 // Get the request with the id after previousRequestId. 00732 PreparedStatement stmt = null; 00733 try 00734 { 00735 ResultSet rs = null; 00736 boolean emptyResult; 00737 00738 do 00739 { 00740 // Take a window of 2 requests if there is a small hole 00741 // induced by a removed begin/commit/rollback command. 00742 stmt = connection.prepareStatement("SELECT * FROM " + logTable 00743 + " WHERE id>? AND id<=? ORDER BY id"); 00744 stmt.setLong(1, previousRequestId); 00745 stmt.setLong(2, previousRequestId + 2); 00746 rs = stmt.executeQuery(); 00747 previousRequestId += 2; // Shift the window 00748 emptyResult = !rs.next(); 00749 } 00750 while (emptyResult && (previousRequestId <= logTableId)); 00751 00752 // No more request after this one 00753 if (emptyResult) 00754 return null; 00755 00756 String sql = rs.getString("sql"); 00757 String user = rs.getString("vlogin"); 00758 int transactionId = rs.getInt("transaction_id"); 00759 int id = rs.getInt("id"); 00760 stmt.close(); 00761 00762 // Construct the request object according to its type 00763 boolean escapeProcessing = true; 00764 sql = sql.trim(); 00765 // Check that the command starts with (only 2 letters are needed) 00766 // in[sert]/up[date]/de[lete]/cr[eate]/dr[op]/be[gin]/co[mmit]/ro[llback]/{c[all]/}c[all] 00767 // (write stored procedure call) 00768 String lower = sql.substring(0, 2).toLowerCase(); 00769 if (lower.equals("in")) 00770 { // insert 00771 AbstractWriteRequest wr = new InsertRequest(sql, escapeProcessing, 00772 timeout); 00773 wr.setLogin(user); 00774 logger.info("insert request"); 00775 if (transactionId != 0) 00776 { 00777 wr.setIsAutoCommit(false); 00778 wr.setTransactionId(transactionId); 00779 } 00780 else 00781 wr.setIsAutoCommit(true); 00782 task = new RecoveryTask(id, new WriteRequestTask(1, 1, wr)); 00783 } 00784 else if (lower.equals("up")) 00785 { // update 00786 AbstractWriteRequest wr = new UpdateRequest(sql, escapeProcessing, 00787 timeout); 00788 wr.setLogin(user); 00789 logger.info("update request"); 00790 if (transactionId != 0) 00791 { 00792 wr.setIsAutoCommit(false); 00793 wr.setTransactionId(transactionId); 00794 } 00795 else 00796 wr.setIsAutoCommit(true); 00797 task = new RecoveryTask(id, new WriteRequestTask(1, 1, wr)); 00798 } 00799 else if (lower.equals("de")) 00800 { // delete 00801 AbstractWriteRequest wr = new DeleteRequest(sql, escapeProcessing, 00802 timeout); 00803 wr.setLogin(user); 00804 logger.info("delete request"); 00805 if (transactionId != 0) 00806 { 00807 wr.setIsAutoCommit(false); 00808 wr.setTransactionId(transactionId); 00809 } 00810 else 00811 wr.setIsAutoCommit(true); 00812 task = new RecoveryTask(id, new WriteRequestTask(1, 1, wr)); 00813 } 00814 else if (lower.equals("cr")) 00815 { // create 00816 AbstractWriteRequest wr = new CreateRequest(sql, escapeProcessing, 00817 timeout); 00818 wr.setLogin(user); 00819 if (transactionId != 0) 00820 { 00821 wr.setIsAutoCommit(false); 00822 wr.setTransactionId(transactionId); 00823 } 00824 else 00825 wr.setIsAutoCommit(true); 00826 task = new RecoveryTask(id, new WriteRequestTask(1, 1, wr)); 00827 } 00828 else if (lower.equals("dr")) 00829 { // drop 00830 AbstractWriteRequest wr = new DropRequest(sql, escapeProcessing, 00831 timeout); 00832 wr.setLogin(user); 00833 if (transactionId != 0) 00834 { 00835 wr.setIsAutoCommit(false); 00836 wr.setTransactionId(transactionId); 00837 } 00838 else 00839 wr.setIsAutoCommit(true); 00840 task = new RecoveryTask(id, new WriteRequestTask(1, 1, wr)); 00841 } 00842 else if (lower.equals("be")) 00843 { // begin 00844 task = new RecoveryTask(id, new BeginTask(1, 1, (long) timeout * 1000, 00845 user, transactionId)); 00846 logger.info("begin"); 00847 } 00848 else if (lower.equals("co")) 00849 { // commit 00850 task = new RecoveryTask(id, new CommitTask(1, 1, (long) timeout * 1000, 00851 user, transactionId)); 00852 logger.info("commit"); 00853 } 00854 else if (lower.equals("ro")) 00855 { // rollback 00856 task = new RecoveryTask(id, new RollbackTask(1, 1, 00857 (long) timeout * 1000, user, transactionId)); 00858 } 00859 else if (lower.equals("{c")) 00860 { // read stored procedure call "{call ...}" 00861 StoredProcedure proc = new StoredProcedure(sql, escapeProcessing, 00862 timeout); 00863 proc.setLogin(user); 00864 if (transactionId != 0) 00865 { 00866 proc.setIsAutoCommit(false); 00867 proc.setTransactionId(transactionId); 00868 } 00869 else 00870 proc.setIsAutoCommit(true); 00871 task = new RecoveryTask(id, new ReadStoredProcedureTask(1, 1, proc)); 00872 logger.info("read stored procedure call"); 00873 } 00874 else if (lower.equals("}c")) 00875 { // write stored procedure call, 00876 // we must replace "}call ...}" with "{call ...}" 00877 StringBuffer writeCall = new StringBuffer(sql); 00878 writeCall.setCharAt(0, '{'); 00879 StoredProcedure proc = new StoredProcedure(writeCall.toString(), 00880 escapeProcessing, timeout); 00881 proc.setLogin(user); 00882 if (transactionId != 0) 00883 { 00884 proc.setIsAutoCommit(false); 00885 proc.setTransactionId(transactionId); 00886 } 00887 else 00888 proc.setIsAutoCommit(true); 00889 task = new RecoveryTask(id, new WriteStoredProcedureTask(1, 1, proc)); 00890 logger.info("read stored procedure call"); 00891 } 00892 else 00893 throw new SQLException(Translate.get("recovery.jdbc.sql.unkwown", sql)); 00894 } 00895 catch (SQLException e) 00896 { 00897 try 00898 { 00899 if (stmt != null) 00900 stmt.close(); 00901 } 00902 catch (Exception ignore) 00903 { 00904 } 00905 throw new SQLException(Translate.get("recovery.jdbc.recover.failed", e)); 00906 } 00907 return task; 00908 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 1022 行で定義されています。
01023 { 01024 PreparedStatement stmt = null; 01025 01026 // Wait for transaction to finish 01027 waitForTransactionsEnd(true); 01028 01029 try 01030 { 01031 // 1. Get the reference point to delete 01032 stmt = connection.prepareStatement("SELECT * from " + checkpointTable 01033 + " WHERE name LIKE ?"); 01034 stmt.setString(1, checkpointName); 01035 ResultSet rs = stmt.executeQuery(); 01036 if (!rs.next()) 01037 throw new SQLException("Checkpoint " + checkpointName 01038 + " does not exist"); 01039 01040 int requestId = rs.getInt("request_id"); 01041 01042 // Delete all entries below 01043 stmt = connection.prepareStatement("DELETE FROM " + logTable 01044 + " WHERE ID <= ?"); 01045 stmt.setInt(1, requestId); 01046 stmt.executeUpdate(); 01047 01048 // Delete checkpoint name 01049 stmt = connection.prepareStatement("DELETE FROM " + checkpointTable 01050 + " WHERE name like ?"); 01051 stmt.setString(1, checkpointName); 01052 stmt.executeUpdate(); 01053 stmt.close(); 01054 } 01055 catch (SQLException e) 01056 { 01057 try 01058 { 01059 if (stmt != null) 01060 stmt.close(); 01061 } 01062 catch (Exception ignore) 01063 { 01064 } 01065 throw new SQLException(Translate.get( 01066 "recovery.jdbc.checkpoint.remove.failed", new String[]{ 01067 checkpointName, e.getMessage()})); 01068 } 01069 01070 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 525 行で定義されています。
00526 { 00527 00528 long transactionId = tm.getTransactionId(); 00529 if (isRecovering()) 00530 { 00531 // Some backends started a recovery process, log the rollback 00532 loggerThread.log(incrementLogTableId(), login, "rollback", transactionId, 00533 false); 00534 } 00535 else 00536 { 00537 // The transaction failed 00538 // Remove the requests with this transactionId from the database 00539 loggerThread.rollbackTransaction(transactionId); 00540 PreparedStatement stmt = null; 00541 try 00542 { 00543 stmt = connection.prepareStatement("DELETE FROM " + logTable 00544 + " WHERE transaction_id=?"); 00545 stmt.setLong(1, transactionId); 00546 stmt.executeUpdate(); 00547 stmt.close(); 00548 } 00549 catch (SQLException e) 00550 { 00551 try 00552 { 00553 if (stmt != null) 00554 stmt.close(); 00555 } 00556 catch (Exception ignore) 00557 { 00558 } 00559 throw new SQLException(Translate.get( 00560 "recovery.jdbc.transaction.remove.failed", new String[]{ 00561 String.valueOf(transactionId), e.getMessage()})); 00562 } 00563 } 00564 } |
|
Sets the backend table create statement
JDBCRecoveryLog.java の 271 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.backendTableCreateStatement, org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.backendTableName, org.objectweb.cjdbc.common.log.Trace.debug(), と org.objectweb.cjdbc.common.log.Trace.isDebugEnabled().
00274 { 00275 this.backendTableName = tableName; 00276 this.backendTableCreateStatement = "CREATE TABLE " + backendTableName 00277 + " (databaseName " + databaseNameType + ", backendName " 00278 + backendNameType + ", checkpointName " + checkpointNameType + " " 00279 + extraStatement + ")"; 00280 00281 if (logger.isDebugEnabled()) 00282 logger.debug(Translate.get("recovery.jdbc.backendtable.statement", 00283 backendTableCreateStatement)); 00284 } |
|
Sets the checkpoint table name and create statement.
JDBCRecoveryLog.java の 240 行で定義されています。 参照先 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.checkpointTableCreateStatement, org.objectweb.cjdbc.common.log.Trace.debug(), と org.objectweb.cjdbc.common.log.Trace.isDebugEnabled().
00242 { 00243 this.checkpointTable = tableName; 00244 this.nameType = nameType; 00245 this.requestIdType = requestIdType; 00246 this.checkextraStatement = extraStatement; 00247 // CREATE TABLE tableName ( 00248 // name checkpointNameColumnType, 00249 // request_id requestIdColumnType, 00250 // extraStatement) 00251 00252 String checkpointTableCreateStatement = "CREATE TABLE " + tableName 00253 + " (name " + nameType + ",request_id " + requestIdType 00254 + extraStatement + ")"; 00255 if (logger.isDebugEnabled()) 00256 logger.debug(Translate.get("recovery.jdbc.checkpointtable.statement", 00257 checkpointTableCreateStatement)); 00258 00259 this.checkpointTableCreateStatement = checkpointTableCreateStatement; 00260 } |
|
Sets the log table name and create statement.
JDBCRecoveryLog.java の 212 行で定義されています。 参照先 org.objectweb.cjdbc.common.log.Trace.debug(), org.objectweb.cjdbc.common.log.Trace.isDebugEnabled(), と org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.logTableCreateStatement.
00215 { 00216 this.logTable = tableName; 00217 this.idType = idType; 00218 this.vloginType = vloginType; 00219 this.sqlType = sqlType; 00220 this.transactionIdType = transactionIdType; 00221 this.logextraStatement = extraStatement; 00222 String logTableCreateStatement = "CREATE TABLE " + tableName + " (id " 00223 + idType + ",vlogin " + vloginType + ",sql " + sqlType 00224 + ",transaction_id " + transactionIdType + extraStatement + ")"; 00225 if (logger.isDebugEnabled()) 00226 logger.debug(Translate.get("recovery.jdbc.logtable.statement", 00227 logTableCreateStatement)); 00228 00229 this.logTableCreateStatement = logTableCreateStatement; 00230 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 1105 行で定義されています。
01107 { 01108 PreparedStatement stmt = null; 01109 PreparedStatement stmt2 = null; 01110 01111 try 01112 { 01113 // 1. Get the reference point to delete 01114 stmt = connection.prepareStatement("SELECT * from " + backendTableName 01115 + " WHERE backendName LIKE ? and databaseName LIKE ?"); 01116 stmt.setString(1, backendName); 01117 stmt.setString(2, databaseName); 01118 ResultSet rs = stmt.executeQuery(); 01119 if (!rs.next()) 01120 { 01121 stmt2 = connection.prepareStatement("INSERT INTO " + backendTableName 01122 + " values('" + databaseName + "','" + backendName + "','" 01123 + checkpoint + "')"); 01124 if (stmt2.executeUpdate() != 1) 01125 throw new SQLException( 01126 "Error while inserting new backend reference. Incorrect number of rows"); 01127 } 01128 else 01129 { 01130 stmt2 = connection.prepareStatement("UPDATE " + backendTableName 01131 + " set checkpointName='" + checkpoint + "' where backendName='" 01132 + backendName + "' and databaseName='" + databaseName + "'"); 01133 if (stmt2.executeUpdate() != 1) 01134 throw new SQLException( 01135 "Error while updating backend reference. Incorrect number of rows"); 01136 } 01137 01138 stmt.close(); 01139 stmt2.close(); 01140 } 01141 catch (SQLException e) 01142 { 01143 e.printStackTrace(); 01144 try 01145 { 01146 if (stmt != null) 01147 stmt.close(); 01148 if (stmt2 != null) 01149 stmt2.close(); 01150 } 01151 catch (Exception ignore) 01152 { 01153 } 01154 throw new SQLException("Unable to update checkpoint '" + checkpoint 01155 + "' for backend:" + backendName); 01156 } 01157 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 619 行で定義されています。
00621 { 00622 PreparedStatement stmt = null; 00623 00624 // Check if a checkpoint with the name checkpointName already exists 00625 if (!validCheckpointName(checkpointName)) 00626 { 00627 throw new SQLException(Translate.get( 00628 "recovery.jdbc.checkpoint.duplicate", checkpointName)); 00629 } 00630 00631 // Wait for transaction to finish 00632 waitForTransactionsEnd(true); 00633 00634 try 00635 { 00636 stmt = connection.prepareStatement("INSERT INTO " + checkpointTable 00637 + " VALUES(?,?)"); 00638 stmt.setString(1, checkpointName); 00639 stmt.setLong(2, requestId); 00640 stmt.executeUpdate(); 00641 stmt.close(); 00642 } 00643 catch (SQLException e) 00644 { 00645 try 00646 { 00647 if (stmt != null) 00648 stmt.close(); 00649 } 00650 catch (Exception ignore) 00651 { 00652 } 00653 throw new SQLException(Translate.get( 00654 "recovery.jdbc.checkpoint.store.failed", new String[]{checkpointName, 00655 e.getMessage()})); 00656 } 00657 } |
|
org.objectweb.cjdbc.controller.recoverylog.AbstractRecoveryLogに実装されています. JDBCRecoveryLog.java の 569 行で定義されています。
00570 { 00571 storeCheckpoint(checkpointName, logTableId); 00572 } |
|
Checks if a checkpoint with the name checkpointName is already stored in the database.
JDBCRecoveryLog.java の 581 行で定義されています。
00583 { 00584 PreparedStatement stmt = null; 00585 ResultSet rs = null; 00586 try 00587 { 00588 stmt = connection.prepareStatement("SELECT * FROM " + checkpointTable 00589 + " WHERE name LIKE ?"); 00590 stmt.setString(1, checkpointName); 00591 rs = stmt.executeQuery(); 00592 00593 // If the query returned any rows, the checkpoint name is already 00594 // in use and therefore invalid. 00595 return !rs.next(); 00596 } 00597 catch (SQLException e) 00598 { 00599 throw new SQLException(Translate.get( 00600 "recovery.jdbc.checkpoint.check.failed", e)); 00601 } 00602 finally 00603 { 00604 try 00605 { 00606 if (stmt != null) 00607 stmt.close(); 00608 } 00609 catch (SQLException ignore) 00610 { 00611 } 00612 } 00613 } |
|
JDBCRecoveryLog.java の 659 行で定義されています。
00660 { 00661 if (forceRollback) 00662 { 00663 loggerThread.rollbackTransactions(); 00664 } 00665 else 00666 { 00667 synchronized (loggerThread) 00668 { 00669 while (!loggerThread.getLogQueueIsEmpty()) 00670 { 00671 try 00672 { 00673 wait(100); 00674 } 00675 catch (Exception e) 00676 { 00677 logger.warn("Exception " + e 00678 + " while waiting for end of transactions"); 00679 } 00680 } 00681 } 00682 } 00683 } |
|
Backend table
JDBCRecoveryLog.java の 97 行で定義されています。 参照元 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.setBackendTableCreateStatement(). |
|
|
JDBCRecoveryLog.java の 103 行で定義されています。 |
|
Checkpoint table name. JDBCRecoveryLog.java の 89 行で定義されています。 参照元 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.intializeDatabase(). |
|
JDBCRecoveryLog.java の 90 行で定義されています。 参照元 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.setCheckpointTableCreateStatement(). |
|
Connection to the database. JDBCRecoveryLog.java の 106 行で定義されています。 |
|
Driver class name. JDBCRecoveryLog.java の 64 行で定義されています。 |
|
Driver name. JDBCRecoveryLog.java の 67 行で定義されています。 |
|
JDBCRecoveryLog.java の 82 行で定義されています。 |
|
JDBCRecoveryLog.java の 86 行で定義されています。 |
|
初期値: Trace
.getLogger("org.objectweb.cjdbc.controller.recoverylog")
AbstractRecoveryLog.java の 49 行で定義されています。 |
|
JDBCRecoveryLog.java の 117 行で定義されています。 参照元 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.checkRecoveryLogTables(). |
|
User's login. JDBCRecoveryLog.java の 73 行で定義されています。 |
|
|
JDBCRecoveryLog.java の 80 行で定義されています。 参照元 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.setLogTableCreateStatement(). |
|
Current maximum value of the primary key in logTable. JDBCRecoveryLog.java の 112 行で定義されています。 参照元 org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.incrementLogTableId(), と org.objectweb.cjdbc.controller.recoverylog.JDBCRecoveryLog.intializeDatabase(). |
|
JDBCRecoveryLog.java の 101 行で定義されています。 |
|
User's password. JDBCRecoveryLog.java の 76 行で定義されています。 |
|
JDBCRecoveryLog.java の 109 行で定義されています。 |
|
JDBCRecoveryLog.java の 102 行で定義されています。 |
|
JDBCRecoveryLog.java の 84 行で定義されています。 |
|
Timeout for SQL requests. JDBCRecoveryLog.java の 115 行で定義されています。 |
|
JDBCRecoveryLog.java の 85 行で定義されています。 |
|
Driver URL. JDBCRecoveryLog.java の 70 行で定義されています。 |
|
JDBCRecoveryLog.java の 83 行で定義されています。 |