📄 idbroker.java
字号:
log.debug("Unscheduled retrieval of more ids for table: " + tableName); } // Increase quantity, so that hopefully this does not // happen again. float rate = getQuantity(tableName, null).floatValue() / (float) timeLapse; quantityStore.put(tableName, new BigDecimal( Math.ceil(SLEEP_PERIOD * rate * SAFETY_MARGIN))); } } lastQueryTime.put(tableName, now); } /** * Grabs more ids from the id_table and stores it in the ids * Hashtable. If adjustQuantity is set to true the amount of id's * retrieved for each call to storeIDs will be adjusted. * * @param tableName The name of the table for which we want an id. * @param adjustQuantity True if amount should be adjusted. * @param connection a Connection * @exception Exception a generic exception. */ private void storeIDs(String tableName, boolean adjustQuantity, Connection connection) throws Exception { BigDecimal nextId = null; BigDecimal quantity = null; DatabaseMap dbMap = tableMap.getDatabaseMap(); // Block on the table. Multiple tables are allowed to ask for // ids simultaneously. // TableMap tMap = dbMap.getTable(tableName); // synchronized(tMap) see comment in the getNextIds method // { if (adjustQuantity) { checkTiming(tableName); } boolean useNewConnection = (connection == null) || (configuration .getBoolean(DB_IDBROKER_USENEWCONNECTION, true)); try { if (useNewConnection) { connection = Transaction.beginOptional(dbMap.getName(), transactionsSupported); } // Write the current value of quantity of keys to grab // to the database, primarily to obtain a write lock // on the table/row, but this value will also be used // as the starting value when an IDBroker is // instantiated. quantity = getQuantity(tableName, connection); updateQuantity(connection, tableName, quantity); // Read the next starting ID from the ID_TABLE. BigDecimal[] results = selectRow(connection, tableName); nextId = results[0]; // NEXT_ID column // Update the row based on the quantity in the // ID_TABLE. BigDecimal newNextId = nextId.add(quantity); updateNextId(connection, tableName, newNextId.toString()); if (useNewConnection) { Transaction.commit(connection); } } catch (Exception e) { if (useNewConnection) { Transaction.rollback(connection); } throw e; } List availableIds = (List) ids.get(tableName); if (availableIds == null) { availableIds = new ArrayList(); ids.put(tableName, availableIds); } // Create the ids and store them in the list of available ids. int numId = quantity.intValue(); for (int i = 0; i < numId; i++) { availableIds.add(nextId); nextId = nextId.add(ONE); } // } } /** * This method allows you to get the number of ids that are to be * cached in memory. This is either stored in quantityStore or * read from the db. (ie the value in ID_TABLE.QUANTITY). * * Though this method returns a BigDecimal for the quantity, it is * unlikey the system could withstand whatever conditions would lead * to really needing a large quantity, it is retrieved as a BigDecimal * only because it is going to be added to another BigDecimal. * * @param tableName The name of the table we want to query. * @param connection a Connection * @return An int with the number of ids cached in memory. */ private BigDecimal getQuantity(String tableName, Connection connection) { BigDecimal quantity = null; // If prefetch is turned off we simply return 1 if (!configuration.getBoolean(DB_IDBROKER_PREFETCH, true)) { quantity = new BigDecimal(1); } // Initialize quantity, if necessary. else if (quantityStore.containsKey(tableName)) { quantity = (BigDecimal) quantityStore.get(tableName); } else { Connection dbCon = null; try { if (connection == null || configuration .getBoolean(DB_IDBROKER_USENEWCONNECTION, true)) { String databaseName = tableMap.getDatabaseMap().getName(); // Get a connection to the db dbCon = Torque.getConnection(databaseName); } // Read the row from the ID_TABLE. BigDecimal[] results = selectRow(dbCon, tableName); // QUANTITY column. quantity = results[1]; quantityStore.put(tableName, quantity); } catch (Exception e) { quantity = new BigDecimal(10); } finally { // Return the connection to the pool. try { dbCon.close(); } catch (Exception e) { log.error("Release of connection failed.", e); } } } return quantity; } /** * Helper method to select a row in the ID_TABLE. * * @param con A Connection. * @param tableName The properly escaped name of the table to * identify the row. * @return A BigDecimal[]. * @exception Exception a generic exception. */ private BigDecimal[] selectRow(Connection con, String tableName) throws Exception { StringBuffer stmt = new StringBuffer(); stmt.append("SELECT " + NEXT_ID + ", " + QUANTITY) .append(" FROM " + ID_TABLE) .append(" WHERE TABLE_NAME = '") .append(tableName) .append('\''); Statement statement = null; BigDecimal[] results = new BigDecimal[2]; try { statement = con.createStatement(); ResultSet rs = statement.executeQuery(stmt.toString()); if (rs.next()) { // work around for MySQL which appears to support // getBigDecimal in the source code, but the binary // is throwing an NotImplemented exception. results[0] = new BigDecimal(rs.getString(1)); // next_id results[1] = new BigDecimal(rs.getString(2)); // quantity } else { throw new TorqueException("The table " + tableName + " does not have a proper entry in the " + ID_TABLE); } } finally { if (statement != null) { statement.close(); } } return results; } /** * Helper method to update a row in the ID_TABLE. * * @param con A Connection. * @param tableName The properly escaped name of the table to identify the * row. * @param id An int with the value to set for the id. * @exception Exception Database error. */ private void updateNextId(Connection con, String tableName, String id) throws Exception { StringBuffer stmt = new StringBuffer(id.length() + tableName.length() + 50); stmt.append("UPDATE " + ID_TABLE) .append(" SET NEXT_ID = ") .append(id) .append(" WHERE TABLE_NAME = '") .append(tableName) .append('\''); Statement statement = null; if (log.isDebugEnabled()) { log.debug("updateNextId: " + stmt.toString()); } try { statement = con.createStatement(); statement.executeUpdate(stmt.toString()); } finally { if (statement != null) { statement.close(); } } } /** * Helper method to update a row in the ID_TABLE. * * @param con A Connection. * @param tableName The properly escaped name of the table to identify the * row. * @param quantity An int with the value of the quantity. * @exception Exception Database error. */ private void updateQuantity(Connection con, String tableName, BigDecimal quantity) throws Exception { StringBuffer stmt = new StringBuffer(quantity.toString().length() + tableName.length() + 50); stmt.append("UPDATE " + ID_TABLE) .append(" SET QUANTITY = ") .append(quantity) .append(" WHERE TABLE_NAME = '") .append(tableName) .append('\''); Statement statement = null; if (log.isDebugEnabled()) { log.debug("updateQuantity: " + stmt.toString()); } try { statement = con.createStatement(); statement.executeUpdate(stmt.toString()); } finally { if (statement != null) { statement.close(); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -