
org.infinispan.server.hotrod.tx.table.TxState Maven / Gradle / Ivy
package org.infinispan.server.hotrod.tx.table;
import static org.infinispan.commons.marshall.MarshallUtil.marshallCollection;
import static org.infinispan.commons.marshall.MarshallUtil.unmarshallCollection;
import static org.infinispan.server.hotrod.tx.table.Status.ACTIVE;
import static org.infinispan.server.hotrod.tx.table.Status.PREPARING;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.infinispan.commands.write.WriteCommand;
import org.infinispan.commons.marshall.AdvancedExternalizer;
import org.infinispan.commons.time.TimeService;
import org.infinispan.remoting.transport.Address;
import org.infinispan.server.core.ExternalizerIds;
import org.infinispan.transaction.xa.GlobalTransaction;
import net.jcip.annotations.Immutable;
/**
* A transaction state stored globally in all the cluster members.
*
* @author Pedro Ruivo
* @since 9.4
*/
@Immutable
public class TxState {
public static final AdvancedExternalizer EXTERNALIZER = new Externalizer();
private final GlobalTransaction globalTransaction;
private final Status status;
private final List modifications;
private final boolean recoverable;
private final long timeout; //ms
private final long lastAccessTimeNs; //ns
public TxState(GlobalTransaction globalTransaction, boolean recoverable, long timeout, TimeService timeService) {
this(globalTransaction, ACTIVE, null, recoverable, timeout, timeService.time());
}
private TxState(GlobalTransaction globalTransaction, Status status, List modifications,
boolean recoverable, long timeout, long accessTime) {
this.globalTransaction = Objects.requireNonNull(globalTransaction);
this.status = Objects.requireNonNull(status);
this.modifications = modifications == null ? null : List.copyOf(modifications);
this.recoverable = recoverable;
this.timeout = timeout;
lastAccessTimeNs = accessTime;
}
public long getTimeout() {
return timeout;
}
public TxState markPreparing(List modifications, TimeService timeService) {
return new TxState(globalTransaction, PREPARING, modifications, recoverable, timeout,
timeService.time());
}
public Address getOriginator() {
return ((ClientAddress) globalTransaction.getAddress()).getLocalAddress();
}
public TxState setStatus(Status newStatus, boolean cleanupModification, TimeService timeService) {
return new TxState(globalTransaction, newStatus, cleanupModification ? null : modifications, recoverable, timeout,
timeService.time());
}
public Status getStatus() {
return status;
}
public GlobalTransaction getGlobalTransaction() {
return globalTransaction;
}
public List getModifications() {
return modifications;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
TxState txState = (TxState) o;
return Objects.equals(status, txState.status) &&
Objects.equals(globalTransaction, txState.globalTransaction);
}
@Override
public int hashCode() {
int result = Objects.hashCode(globalTransaction);
result = 31 * result + Objects.hashCode(status);
return result;
}
public boolean hasTimedOut(long currentTimeNs) {
long timeoutNs = TimeUnit.MILLISECONDS.toNanos(timeout);
return lastAccessTimeNs + timeoutNs < currentTimeNs;
}
public boolean isRecoverable() {
return recoverable;
}
public boolean isSameAs(GlobalTransaction globalTransaction, boolean recoverable, long timeout) {
return this.timeout == timeout &&
this.recoverable == recoverable &&
this.globalTransaction.equals(globalTransaction) &&
status == ACTIVE;
}
@Override
public String toString() {
return "TxState{" +
"globalTransaction=" + globalTransaction +
", status=" + status +
", modifications=" + modifications +
", recoverable=" + recoverable +
", timeout=" + timeout +
", lastAccessTime=" + lastAccessTimeNs +
'}';
}
private static class Externalizer implements AdvancedExternalizer {
@Override
public Set> getTypeClasses() {
return Collections.singleton(TxState.class);
}
@Override
public Integer getId() {
return ExternalizerIds.TX_STATE;
}
@Override
public void writeObject(ObjectOutput output, TxState object) throws IOException {
output.writeObject(object.globalTransaction);
Status.writeTo(output, object.status);
marshallCollection(object.modifications, output);
output.writeBoolean(object.recoverable);
output.writeLong(object.timeout);
output.writeLong(object.lastAccessTimeNs);
}
@Override
public TxState readObject(ObjectInput input) throws IOException, ClassNotFoundException {
return new TxState((GlobalTransaction) input.readObject(),
Status.readFrom(input),
unmarshallCollection(input, ArrayList::new),
input.readBoolean(), input.readLong(), input.readLong());
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy