在以前的版本jaybird(2.2),我是能夠執行服務API來火鳥服務器,以獲得活動事務標記:OIT,燕麥,下一首等Jaybird 3和Firebird交易信息
在3.0版本中,我無法找到如何正確地做到這一點。只有ISC常量(如isc_info_oldest_snapshot),但沒有方法。
所以,我看到了一種方法:通過StatisticsManager
獲取數據庫頭的查詢。但它不是那麼容易,因爲它會返回一個需要解析的文本:
,現在我需要解析的文字:
Database "C:\FIREBIRD\3.0.2\EXAMPLES\EMPBUILD\EMPLOYEE.FDB"
Database header page information:
Flags 0
Generation 806
System Change Number 12
Page size 8192
ODS version 12.0
Oldest transaction 520
Oldest active 521
Oldest snapshot 521
Next transaction 521
Sequence number 0
Next attachment ID 857
Implementation HW=AMD/Intel/x64 little-endian OS=Windows CC=MSVC
Shadow count 0
Page buffers 0
Next header page 0
Database dialect 3
Creation date Apr 15, 2016 17:38:34
Attributes
Variable header data:
Database backup GUID: {6F41E937-76D5-4C67-6CAE-F8556AD27BEE}
Database GUID: {EE5B2713-7B17-43B0-0CB3-0616B4B8A63D}
*END*
可能就可以得到直接值?
UPD:代碼舊版本是:
/** [ActiveCount, OAT, OST, OIT, Next] */
public static int[] getTxInfo(final GDS gds,
final String host,
final int port,
final String databasePath,
final String user,
final String password) throws Exception {
final byte[] queryItems = {
ISCConstants.isc_info_oldest_transaction,
ISCConstants.isc_info_oldest_active,
ISCConstants.isc_info_oldest_snapshot,
ISCConstants.isc_info_next_transaction,
ISCConstants.isc_info_active_transactions,
ISCConstants.isc_info_end
};
byte[] response = queryDB(
gds, host, port, databasePath, user, password,
queryItems, DEFAULT_BUFFER_SIZE
);
int i = 0;
final int[] result = new int[5];
while (response[i] != ISCConstants.isc_info_end) {
final byte code = response[i++];
switch (code) {
case ISCConstants.isc_info_active_transactions: {
//здесь идет столько блоков isc_info_active_transactions, сколько
//реально активных транзакций в данный момент
final int valueLen = gds.iscVaxInteger(response, i, LENGTH_LEN);
i += LENGTH_LEN;
//final int res = gds.iscVaxInteger(response, i, valueLen);
i += valueLen;
result[0]++;
break;
}
case ISCConstants.isc_info_oldest_active: {
final int valueLen = gds.iscVaxInteger(response, i, LENGTH_LEN);
i += LENGTH_LEN;
final int res = gds.iscVaxInteger(response, i, valueLen);
i += valueLen;
result[1] = res;
break;
}
case ISCConstants.isc_info_oldest_snapshot: {
final int valueLen = gds.iscVaxInteger(response, i, LENGTH_LEN);
i += LENGTH_LEN;
final int res = gds.iscVaxInteger(response, i, valueLen);
i += valueLen;
result[2] = res;
break;
}
case ISCConstants.isc_info_oldest_transaction: {
final int valueLen = gds.iscVaxInteger(response, i, LENGTH_LEN);
i += LENGTH_LEN;
final int res = gds.iscVaxInteger(response, i, valueLen);
i += valueLen;
result[3] = res;
break;
}
case ISCConstants.isc_info_next_transaction: {
final int valueLen = gds.iscVaxInteger(response, i, LENGTH_LEN);
i += LENGTH_LEN;
final int res = gds.iscVaxInteger(response, i, valueLen);
i += valueLen;
result[4] = res;
break;
}
case ISCConstants.isc_info_truncated: {
//этот код означает "буфер слишком маленький, дайте больше"
//обычно это бывает когда слишком много активных транзакций
//сначала пробуем увеличить буфер
if (response.length == DEFAULT_BUFFER_SIZE) {
response = queryDB(
gds, host, port, databasePath, user, password,
queryItems, 32 * DEFAULT_BUFFER_SIZE
);
result[0] = 0;//на всякий случай
//начинаем разбор заново
i = 0;
} else {
//32Кб буфера оказалось тоже недостаточно -- пичалька. Но
//делать нечего -- просто обойдемся без числа активных транзакций
response = queryDB(
gds, host, port, databasePath, user, password,
new byte[]{
ISCConstants.isc_info_oldest_transaction,
ISCConstants.isc_info_oldest_active,
ISCConstants.isc_info_oldest_snapshot,
ISCConstants.isc_info_next_transaction,
ISCConstants.isc_info_end
}, DEFAULT_BUFFER_SIZE
);
result[0] = -1;
//начинаем разбор заново
i = 0;
}
break;
}
default:
throw new FBSQLException("Unrecognized response code: " + code + " (response=" + Arrays.toString(result) + ")");
}
}
return result;
}
其中
public static byte[] queryDB(final GDS gds,
final String host,
final int port,
final String databasePath,
final String user,
final String password,
final byte[] queryItems,
final int bufferLength) throws Exception {
return doWithDB(
gds, host, port, databasePath, user, password,
new DBOperation<byte[]>() {
public byte[] doWithDB(final GDS gds,
final IscDbHandle db) throws GDSException {
return gds.iscDatabaseInfo(
db,
queryItems,
bufferLength
);
}
}
);
}
是否足夠?
您可以繼承'FBServiceManager'並自己獲取信息。我會看看我是否可以將它添加到'FBStatisticsManager'(或者如果我像上次一樣忽略它)。 –
它會很好!我需要事務標記來檢查一些間隙和掃描... –
我爲此創建了[JDBC-485](http://tracker.firebirdsql.org/browse/JDBC-485)。根據當前的時間表,我會在可用時更新,可能會在一兩週內更新。 –