// This could mess with any readers or reverse readers that are open, or anything that might try // to do a log lookup. // This should only be used to roll back buffered updates, not actually applied updates. public void rollback(long pos) throws IOException { synchronized (this) { assert snapshot_size == pos; fos.flush(); raf.setLength(pos); fos.setWritten(pos); assert fos.size() == pos; numRecords = snapshot_numRecords; } }
TransactionLog(File tlogFile, Collection<String> globalStrings, boolean openExisting) { boolean success = false; try { if (debug) { log.debug( "New TransactionLog file=" + tlogFile + ", exists=" + tlogFile.exists() + ", size=" + tlogFile.length() + ", openExisting=" + openExisting); } this.tlogFile = tlogFile; raf = new RandomAccessFile(this.tlogFile, "rw"); long start = raf.length(); channel = raf.getChannel(); os = Channels.newOutputStream(channel); fos = new FastOutputStream(os, new byte[65536], 0); // fos = FastOutputStream.wrap(os); if (openExisting) { if (start > 0) { readHeader(null); raf.seek(start); assert channel.position() == start; fos.setWritten(start); // reflect that we aren't starting at the beginning assert fos.size() == channel.size(); } else { addGlobalStrings(globalStrings); } } else { if (start > 0) { log.warn("New transaction log already exists:" + tlogFile + " size=" + raf.length()); return; } if (start > 0) { raf.setLength(0); } addGlobalStrings(globalStrings); } success = true; assert ObjectReleaseTracker.track(this); } catch (IOException e) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, e); } finally { if (!success && raf != null) { try { raf.close(); } catch (Exception e) { log.error("Error closing tlog file (after error opening)", e); } } } }