io.seata.core.exception.AbstractExceptionHandler Maven / Gradle / Ivy
/*
* Copyright 1999-2019 Seata.io Group.
*
* 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.
*/
package io.seata.core.exception;
import java.util.Objects;
import io.seata.config.Configuration;
import io.seata.config.ConfigurationFactory;
import io.seata.core.constants.ConfigurationKeys;
import io.seata.core.model.LockStatus;
import io.seata.core.protocol.ResultCode;
import io.seata.core.protocol.transaction.AbstractTransactionRequest;
import io.seata.core.protocol.transaction.AbstractTransactionResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static io.seata.core.exception.TransactionExceptionCode.LockKeyConflict;
import static io.seata.core.exception.TransactionExceptionCode.LockKeyConflictFailFast;
/**
* The type Abstract exception handler.
*
* @author sharajava
*/
public abstract class AbstractExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractExceptionHandler.class);
/**
* The constant CONFIG.
*/
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
/**
* The interface Callback.
*
* @param the type parameter
* @param the type parameter
*/
public interface Callback {
/**
* Execute.
*
* @param request the request
* @param response the response
* @throws TransactionException the transaction exception
*/
void execute(T request, S response) throws TransactionException;
/**
* On success.
*
* @param request the request
* @param response the response
*/
void onSuccess(T request, S response);
/**
* onTransactionException
*
* @param request the request
* @param response the response
* @param exception the exception
*/
void onTransactionException(T request, S response, TransactionException exception);
/**
* on other exception
*
* @param request the request
* @param response the response
* @param exception the exception
*/
void onException(T request, S response, Exception exception);
}
/**
* The type Abstract callback.
*
* @param the type parameter
* @param the type parameter
*/
public abstract static class AbstractCallback
implements Callback {
@Override
public void onSuccess(T request, S response) {
response.setResultCode(ResultCode.Success);
}
@Override
public void onTransactionException(T request, S response,
TransactionException tex) {
response.setTransactionExceptionCode(tex.getCode());
response.setResultCode(ResultCode.Failed);
response.setMsg("TransactionException[" + tex.getMessage() + "]");
}
@Override
public void onException(T request, S response, Exception rex) {
response.setResultCode(ResultCode.Failed);
response.setMsg("RuntimeException[" + rex.getMessage() + "]");
}
}
/**
* Exception handle template.
*
* @param the type parameter
* @param the type parameter
* @param callback the callback
* @param request the request
* @param response the response
*/
public void exceptionHandleTemplate(Callback callback, T request, S response) {
try {
callback.execute(request, response);
callback.onSuccess(request, response);
} catch (TransactionException tex) {
if (Objects.equals(LockKeyConflict, tex.getCode())) {
LOGGER.info("this request cannot acquire global lock, you can let Seata retry by setting config [{}] = false or manually retry by yourself. request: {}",
ConfigurationKeys.CLIENT_LOCK_RETRY_POLICY_BRANCH_ROLLBACK_ON_CONFLICT, request);
} else if (Objects.equals(LockKeyConflictFailFast, tex.getCode())) {
LOGGER.info("this request cannot acquire global lock, decide fail-fast because LockStatus is {}. request: {}",
LockStatus.Rollbacking, request);
} else {
LOGGER.error("Catch TransactionException while do RPC, request: {}", request, tex);
}
callback.onTransactionException(request, response, tex);
} catch (RuntimeException rex) {
LOGGER.error("Catch RuntimeException while do RPC, request: {}", request, rex);
callback.onException(request, response, rex);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy