transactionlog.java
来自「一个java方面的消息订阅发送的源码」· Java 代码 · 共 441 行 · 第 1/2 页
JAVA
441 行
/**
* Close the transaction log
*
* @throws TransactionLogException - if it fails to close the log
*/
public void close()
throws TransactionLogException {
try {
if (_dos != null) {
_dos.close();
}
} catch (IOException exception) {
throw new TransactionLogException("Error in close " +
exception.toString());
}
}
/**
* Return the size of the transaction log file.
*
* @return long - the length of the file
*/
public long size() {
return _size;
}
/**
* Force a recovery of this log file. This will close the output file stream
* if one is opened and then read each entry from the log file and send it to
* the specified listener, if one is allocated.
* <p>
* The returned data structure is a HashMap, where the key is a
* {@link ExternalXid} and the entries are LinkedList of {@link
* BaseTransactionLogEntry} objects
*
* @return HashMap - a list of open transactions
* @throws TransactionLogException - if there is a prob recovering
*/
public synchronized HashMap recover()
throws TransactionLogException {
return getOpenTransactionList();
}
/**
* Check if we can garbage collect this transaction log. It will go through
* the log file and check to see whether there are any open transaction. If
* there are no open transactions the it is a candidate for garage collection
*
* @return boolean - true if we can garbage collect; false otherwise
*/
public synchronized boolean canGarbageCollect() {
boolean result = false;
try {
HashMap records = getOpenTransactionList();
if (records.size() == 0) {
result = true;
}
} catch (Exception ignore) {
ignore.printStackTrace();
}
return result;
}
/**
* Destroy this transaction log, which basically removes it from the
* file system
*
* @throws TransactionLogException
*/
public synchronized void destroy()
throws TransactionLogException {
try {
close();
if (!(new File(_name)).delete()) {
_log.error("Failed to destroy " + _name);
}
} catch (Exception exception) {
throw new TransactionLogException("Error in destroy " +
exception.toString());
}
}
// override Object.equals
public boolean equals(Object obj) {
boolean result = false;
if ((obj instanceof TransactionLog) &&
(((TransactionLog) obj)._name.equals(_name))) {
result = true;
}
return result;
}
/**
* Return an instance of the output stream. If one does not exist then
* create it.
*
* @return DataOutputStream - the output stream
*/
private DataOutputStream getOutputStream()
throws IOException, FileNotFoundException {
if (_dos == null) {
_dos = new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream(_name, true)));
}
return _dos;
}
/**
* Return a list of open transactions in a HashMap. The key is the transaction
* id and the data is a vector of associated data records in a LinkedList
*
* @return HashMap
* @throws TransactionLogException - if there is a prob recovering
*/
private HashMap getOpenTransactionList()
throws TransactionLogException {
HashMap records = new HashMap();
// if the output stream is opened then close it
try {
if (_dos != null) {
_dos.close();
_dos = null;
}
} catch (Exception exception) {
throw new TransactionLogException("Error in recover " +
exception.toString());
}
FileInputStream fis = null;
try {
fis = new FileInputStream(_name);
DataInputStream dis = new DataInputStream(new BufferedInputStream(fis));
while (dis.available() > 0) {
byte[] blob = new byte[(int) dis.readLong()];
dis.readFully(blob);
Object object = SerializationHelper.deserialize(blob);
if (object instanceof StateTransactionLogEntry) {
StateTransactionLogEntry state = (StateTransactionLogEntry) object;
LinkedList list = null;
switch (state.getState().getOrd()) {
case TransactionState.OPENED_ORD:
if (records.containsKey(state.getExternalXid())) {
_log.error("OPENED_ORD : Transaction log is inconsistent");
continue;
}
list = new LinkedList();
records.put(state.getExternalXid(), list);
list.add(state);
break;
case TransactionState.PREPARED_ORD:
list = (LinkedList) records.get(state.getExternalXid());
if (list == null) {
_log.error("PREPARED_ORD : Transaction log is inconsistent");
continue;
}
list.add(state);
break;
case TransactionState.CLOSED_ORD:
if (records.get(state.getExternalXid()) == null) {
_log.error("CLOSED_ORD : Transaction log is inconsistent");
continue;
}
records.remove(state.getExternalXid());
break;
default:
break;
}
} else if (object instanceof DataTransactionLogEntry) {
DataTransactionLogEntry data = (DataTransactionLogEntry) object;
LinkedList list = (LinkedList) records.get(data.getExternalXid());
if (list == null) {
_log.error("DATA : Transaction log is inconsistent");
continue;
}
list.add(data);
} else {
System.err.println("There is no support for log entry " +
"records of type " + object.getClass().getName());
}
}
} catch (Exception exception) {
throw new TransactionLogException("Error in recover " +
exception.toString());
} finally {
if (fis != null) {
try {
fis.close();
} catch (Exception exception) {
throw new TransactionLogException("Error in recover " +
exception.toString());
}
}
}
return records;
}
} //-- TransactionLog
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?