
com.arcadedb.server.ha.message.TxRequest Maven / Gradle / Ivy
The newest version!
/*
* Copyright © 2021-present Arcade Data Ltd ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
* SPDX-License-Identifier: Apache-2.0
*/
package com.arcadedb.server.ha.message;
import com.arcadedb.database.Binary;
import com.arcadedb.database.DatabaseInternal;
import com.arcadedb.engine.ComponentFile;
import com.arcadedb.engine.WALException;
import com.arcadedb.engine.WALFile;
import com.arcadedb.log.LogManager;
import com.arcadedb.server.ArcadeDBServer;
import com.arcadedb.server.ha.HAServer;
import com.arcadedb.server.ha.ReplicationException;
import java.nio.channels.*;
import java.util.*;
import java.util.logging.*;
/**
* Replicate a transaction. No response is expected.
*/
public class TxRequest extends TxRequestAbstract {
private boolean waitForResponse;
public DatabaseChangeStructureRequest changeStructure;
public long installDatabaseLastLogNumber = -1;
public TxRequest() {
}
public TxRequest(final String dbName, final Map bucketRecordDelta, final Binary bufferChanges,
final boolean waitForResponse) {
super(dbName, bucketRecordDelta, bufferChanges);
this.waitForResponse = waitForResponse;
}
@Override
public void toStream(final Binary stream) {
stream.putByte((byte) (waitForResponse ? 1 : 0));
if (changeStructure != null) {
stream.putByte((byte) 1);
changeStructure.toStream(stream);
} else
stream.putByte((byte) 0);
super.toStream(stream);
}
@Override
public void fromStream(final ArcadeDBServer server, final Binary stream) {
waitForResponse = stream.getByte() == 1;
if (stream.getByte() == 1) {
changeStructure = new DatabaseChangeStructureRequest();
changeStructure.fromStream(server, stream);
}
super.fromStream(server, stream);
}
@Override
public HACommand execute(final HAServer server, final String remoteServerName, final long messageNumber) {
final DatabaseInternal db = server.getServer().getDatabase(databaseName);
if (!db.isOpen())
throw new ReplicationException("Database '" + databaseName + "' is closed");
if (changeStructure != null)
try {
// APPLY CHANGE OF STRUCTURE FIRST
changeStructure.updateFiles(db);
// RELOAD THE SCHEMA BUT NOT INITIALIZE THE COMPONENTS (SOME NEW PAGES COULD BE IN THE TX ITSELF)
db.getSchema().getEmbedded().load(ComponentFile.MODE.READ_WRITE, false);
} catch (final Exception e) {
LogManager.instance().log(this, Level.SEVERE, "Error on changing database structure request from the leader node", e);
throw new ReplicationException("Error on changing database structure request from the leader node", e);
}
final WALFile.WALTransaction walTx = readTxFromBuffer();
try {
LogManager.instance()
.log(this, Level.FINE, "Applying tx %d from server %s (modifiedPages=%d)...", walTx.txId, remoteServerName,
walTx.pages.length);
final boolean ignoreErrors = installDatabaseLastLogNumber > -1 && messageNumber <= installDatabaseLastLogNumber;
db.getTransactionManager().applyChanges(walTx, bucketRecordDelta, ignoreErrors);
} catch (final WALException e) {
if (e.getCause() instanceof ClosedChannelException) {
// CLOSE THE ENTIRE DB
LogManager.instance()
.log(this, Level.SEVERE, "Closed file during transaction, closing the entire database (error=%s)", e.toString());
db.getEmbedded().close();
}
throw e;
}
if (changeStructure != null)
// INITIALIZE THE COMPONENTS (SOME NEW PAGES COULD BE IN THE TX ITSELF)
db.getSchema().getEmbedded().initComponents();
if (waitForResponse)
return new OkResponse();
return null;
}
@Override
public String toString() {
return "tx(" + databaseName + ")";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy