blob: 04882e07a6f23bf96c3340a11ef5ac5c9fa09280 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.
*/
package org.apache.phoenix.util;
import java.sql.SQLException;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.HTableInterface;
import org.apache.phoenix.coprocessor.MetaDataProtocol.MetaDataMutationResult;
import org.apache.phoenix.exception.SQLExceptionCode;
import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.execute.MutationState;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.schema.PTable;
import org.apache.tephra.TransactionConflictException;
import org.apache.tephra.TransactionFailureException;
import org.apache.tephra.TxConstants;
import org.apache.tephra.hbase.TransactionAwareHTable;
public class TransactionUtil {
private TransactionUtil() {
}
public static boolean isDelete(Cell cell) {
return (CellUtil.matchingValue(cell, HConstants.EMPTY_BYTE_ARRAY));
}
public static long convertToNanoseconds(long serverTimeStamp) {
return serverTimeStamp * TxConstants.MAX_TX_PER_MS;
}
public static long convertToMilliseconds(long serverTimeStamp) {
return serverTimeStamp / TxConstants.MAX_TX_PER_MS;
}
public static SQLException getTransactionFailureException(TransactionFailureException e) {
if (e instanceof TransactionConflictException) {
return new SQLExceptionInfo.Builder(SQLExceptionCode.TRANSACTION_CONFLICT_EXCEPTION)
.setMessage(e.getMessage())
.setRootCause(e)
.build().buildException();
}
return new SQLExceptionInfo.Builder(SQLExceptionCode.TRANSACTION_FAILED)
.setMessage(e.getMessage())
.setRootCause(e)
.build().buildException();
}
public static TransactionAwareHTable getTransactionAwareHTable(HTableInterface htable, boolean isImmutableRows) {
// Conflict detection is not needed for tables with write-once/append-only data
return new TransactionAwareHTable(htable, isImmutableRows ? TxConstants.ConflictDetection.NONE : TxConstants.ConflictDetection.ROW);
}
// we resolve transactional tables at the txn read pointer
public static long getResolvedTimestamp(PhoenixConnection connection, boolean isTransactional, long defaultResolvedTimestamp) {
MutationState mutationState = connection.getMutationState();
Long scn = connection.getSCN();
return scn != null ? scn : (isTransactional && mutationState.isTransactionStarted()) ? convertToMilliseconds(mutationState.getInitialWritePointer()) : defaultResolvedTimestamp;
}
public static long getResolvedTime(PhoenixConnection connection, MetaDataMutationResult result) {
PTable table = result.getTable();
boolean isTransactional = table!=null && table.isTransactional();
return getResolvedTimestamp(connection, isTransactional, result.getMutationTime());
}
public static long getResolvedTimestamp(PhoenixConnection connection, MetaDataMutationResult result) {
PTable table = result.getTable();
MutationState mutationState = connection.getMutationState();
boolean txInProgress = table != null && table.isTransactional() && mutationState.isTransactionStarted();
return txInProgress ? convertToMilliseconds(mutationState.getInitialWritePointer()) : result.getMutationTime();
}
public static Long getTableTimestamp(PhoenixConnection connection, boolean transactional) throws SQLException {
Long timestamp = null;
if (!transactional) {
return timestamp;
}
MutationState mutationState = connection.getMutationState();
if (!mutationState.isTransactionStarted()) {
mutationState.startTransaction();
}
timestamp = convertToMilliseconds(mutationState.getInitialWritePointer());
return timestamp;
}
}