boolean inUserCode = false;
try {
logOutputBuffer.reset();
TransactionId transactionId = xact.getId();
// write out the log header with the operation embedded
logRecord.setValue(transactionId, compensation);
inUserCode = true;
logicalOut.writeObject(logRecord);
inUserCode = false;
// write out the undoInstant
logicalOut.writeLong(((LogCounter)undoInstant).getValueAsLong());
// in this implemetaion, there is no optional data for the
// compensation operation. Optional data for the rollback comes
// from the undoable operation - and is passed into this call.
int completeLength = logOutputBuffer.getPosition();
long instant = 0;
if (logFactory.databaseEncrypted())
{
// we must pad the encryption data to be multiple of block
// size, which is logFactory.getEncryptionBlockSize()
int encryptedLength = completeLength;
if ((encryptedLength % logFactory.getEncryptionBlockSize()) != 0)
encryptedLength = encryptedLength + logFactory.getEncryptionBlockSize() - (encryptedLength % logFactory.getEncryptionBlockSize());
if (encryptionBuffer == null ||
encryptionBuffer.length < encryptedLength)
encryptionBuffer = new byte[encryptedLength];
System.arraycopy(logOutputBuffer.getByteArray(), 0,
encryptionBuffer, 0, completeLength);
// do not bother to clear out the padding area
int len =
logFactory.encrypt(encryptionBuffer, 0, encryptedLength,
encryptionBuffer, 0);
if (SanityManager.DEBUG)
SanityManager.ASSERT(len == encryptedLength,
"encrypted log buffer length != log buffer len");
instant = logFactory.
appendLogRecord(encryptionBuffer,
0, encryptedLength, null, 0, 0);
}
else
{
instant = logFactory.
appendLogRecord(logOutputBuffer.getByteArray(),
0, completeLength, null, 0, 0);
}
LogInstant logInstant = new LogCounter(instant);
if (SanityManager.DEBUG)
{
if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))
{
SanityManager.DEBUG(
LogToFile.DBG_FLAG,
"Write CLR: Xact: " + transactionId.toString() +
"clrinstant: " + logInstant.toString() +
" undoinstant " + undoInstant + "\n");
}
}