/** * This is called when a client looks up a key which isn't contained in the grid. The grid then * calls this method to fetch the values for the keys. If a key doesn't exist in the backend then * Loader.KEY_NOT_FOUND is returned. */ @SuppressWarnings("unchecked") public List get(TxID tx, List keys, boolean arg2) throws LoaderException { LoaderMBeanImpl mbean = WXSUtils.getLoaderMBeanManager() .getBean(tx.getSession().getObjectGrid().getName(), mapName); try { mbean.getGetSizeMetrics().logTime(keys.size()); long startNS = System.nanoTime(); // Get a Data instance for these database selects Connection conn = getConnection(tx); // list for the results ArrayList<Object> rc = new ArrayList<Object>(); Iterator<Object> iter = keys.iterator(); ValueHolder v = new ValueHolder(); NamedParameterStatement s = new NamedParameterStatement(conn, selectSQL); // for each key in the list while (iter.hasNext()) { Object keyValue = iter.next(); Object value = null; // wrap with a Key object for purequery if needed if (keyAttributeColumn != null) { v._wxsutil_value = keyValue; copyPojoToStatement(s, v, keyFieldNames, keyFields); } else { copyPojoToStatement(s, keyValue, keyFieldNames, keyFields); } ResultSet rs = s.executeQuery(); if (rs.first()) { value = copyResultSetToPojo(rs, theClass, normalFields); } // if we found the value then add it otherwise add KEY_NOT_FOUND if (value != null) { rc.add(value); if (logger.isLoggable(Level.FINE)) logger.fine("Found " + keyValue + " in " + tableName + " = " + value); } else { rc.add(Loader.KEY_NOT_FOUND); if (logger.isLoggable(Level.FINE)) logger.fine("Cant find " + keyValue + " in " + tableName); } } mbean.getGetMetrics().logTime(System.nanoTime() - startNS); return rc; } catch (Exception e) { logger.log(Level.SEVERE, "Unexpected exception in get", e); mbean.getGetMetrics().logException(e); throw new LoaderException(e); } }
/** * This is called to write changes at the end of a transaction or a flush to the backend this * Loader works with which in this case in a database. We use purequery to flush everything in a * single batch statement. Purequery does the POJO attribute to SQL parameter work for us. */ public void batchUpdate(TxID tx, LogSequence ls) throws LoaderException, OptimisticCollisionException { mapName = ls.getMapName(); LoaderMBeanImpl mbean = WXSUtils.getLoaderMBeanManager() .getBean(tx.getSession().getObjectGrid().getName(), ls.getMapName()); mbean.getBatchSizeMetrics().logTime(ls.size()); long startNS = System.nanoTime(); // start a hetero batch. // make empty lists for the objects that are inserted or updated or deleted ArrayList<LogElement> iList = new ArrayList<LogElement>(1000); ArrayList<LogElement> uList = new ArrayList<LogElement>(1000); ArrayList<LogElement> dList = new ArrayList<LogElement>(1000); try { // get the Data instance for this transaction Connection conn = getConnection(tx); // data.startBatch(HeterogeneousBatchKind.heterogeneousModify__); // get the changes in this transaction Iterator<LogElement> iter = ls.getPendingChanges(); // the key object. We may need to wrap primitive POJOs (Long, Integer etc) with a wrapped // with a key attribute for purequery. while (iter.hasNext()) { // get next transaction change LogElement e = iter.next(); switch (e.getType().getCode()) { case LogElement.CODE_INSERT: // add to insert POJO list iList.add(e); break; case LogElement.CODE_UPDATE: uList.add(e); // add to update POJO list break; case LogElement.CODE_DELETE: // add to delete POJO list dList.add(e); break; } } // execute the statements within the batch for each type of operation if (iList.size() > 0) { if (logger.isLoggable(Level.FINE)) logger.fine("Inserting " + ls.getMapName() + " " + iList.toString()); copyPojoListToBatch( conn, insertSQL, iList, normalFields, normalFieldNames, keyFields, keyFieldNames); } if (uList.size() > 0) { if (logger.isLoggable(Level.FINE)) logger.fine("Updating " + ls.getMapName() + " " + uList.toString()); copyPojoListToBatch( conn, updateSQL, uList, normalFields, normalFieldNames, keyFields, keyFieldNames); } if (dList.size() > 0) { if (logger.isLoggable(Level.FINE)) logger.fine("Deleting " + ls.getMapName() + " " + dList.toString()); copyPojoListToBatch( conn, deleteSQL, dList, normalFields, normalFieldNames, keyFields, keyFieldNames); } mbean.recordOperationRows(iList.size(), uList.size(), dList.size()); mbean.getBatchUpdateMetrics().logTime(System.nanoTime() - startNS); } catch (SQLException e) { logger.log(Level.SEVERE, "SQL exception processing changes", e); mbean.getBatchUpdateMetrics().logException(e); throw new LoaderException("Map " + ls.getMapName(), e); } catch (Exception e) { logger.log(Level.SEVERE, "Unexpected exception processing update", e); mbean.getBatchUpdateMetrics().logException(e); throw new LoaderException("Map " + ls.getMapName(), e); } }