♻️ Refactoring code. javaformat
This commit is contained in:
1 parent
510061cc75
commit
4600e21f3d
97 files changed
+10718
-10585
No files matched your search
+4
-5
@@ -39,20 +39,19 @@ public class ClientDetailsInitRunner implements InitializingBean {
|
||||
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
|
||||
/**
|
||||
* WebServerInitializedEvent
|
||||
* 使用 TransactionalEventListener 时启动时无法获取到事件
|
||||
* WebServerInitializedEvent 使用 TransactionalEventListener 时启动时无法获取到事件
|
||||
*/
|
||||
@Async
|
||||
@Order
|
||||
@EventListener({ WebServerInitializedEvent.class })
|
||||
public void WebServerInit(){
|
||||
public void WebServerInit() {
|
||||
this.initClientDetails();
|
||||
}
|
||||
|
||||
@Async
|
||||
@Order
|
||||
@TransactionalEventListener({ ClientDetailsInitEvent.class})
|
||||
@TransactionalEventListener({ ClientDetailsInitEvent.class })
|
||||
public void initClientDetails() {
|
||||
log.debug("初始化客户端信息开始 ");
|
||||
|
||||
|
||||
+2
-5
@@ -60,18 +60,15 @@ public class DynamicRouteInitRunner implements InitializingBean {
|
||||
private final RedisMessageListenerContainer listenerContainer;
|
||||
|
||||
/**
|
||||
* WebServerInitializedEvent
|
||||
* 使用 TransactionalEventListener 时启动时无法获取到事件
|
||||
* WebServerInitializedEvent 使用 TransactionalEventListener 时启动时无法获取到事件
|
||||
*/
|
||||
@Async
|
||||
@Order
|
||||
@EventListener({ WebServerInitializedEvent.class })
|
||||
public void WebServerInit(){
|
||||
public void WebServerInit() {
|
||||
this.initRoute();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Async
|
||||
@Order
|
||||
@TransactionalEventListener({ DynamicRouteInitEvent.class })
|
||||
|
||||
+265
-266
@@ -34,294 +34,293 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public abstract class AbstractTCInboundHandler extends AbstractExceptionHandler implements TCInboundHandler {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTCInboundHandler.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractTCInboundHandler.class);
|
||||
|
||||
@Override
|
||||
public GlobalBeginResponse handle(GlobalBeginRequest request, final RpcContext rpcContext) {
|
||||
GlobalBeginResponse response = new GlobalBeginResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalBeginRequest, GlobalBeginResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalBeginRequest request, GlobalBeginResponse response) throws TransactionException {
|
||||
try {
|
||||
doGlobalBegin(request, response, rpcContext);
|
||||
} catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore,
|
||||
String.format("begin global request failed. xid=%s, msg=%s", response.getXid(), e.getMessage()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
@Override
|
||||
public GlobalBeginResponse handle(GlobalBeginRequest request, final RpcContext rpcContext) {
|
||||
GlobalBeginResponse response = new GlobalBeginResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalBeginRequest, GlobalBeginResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalBeginRequest request, GlobalBeginResponse response) throws TransactionException {
|
||||
try {
|
||||
doGlobalBegin(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"begin global request failed. xid=%s, msg=%s", response.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global begin.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalBegin(GlobalBeginRequest request, GlobalBeginResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
/**
|
||||
* Do global begin.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalBegin(GlobalBeginRequest request, GlobalBeginResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalCommitResponse handle(GlobalCommitRequest request, final RpcContext rpcContext) {
|
||||
GlobalCommitResponse response = new GlobalCommitResponse();
|
||||
response.setGlobalStatus(GlobalStatus.Committing);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalCommitRequest, GlobalCommitResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalCommitRequest request, GlobalCommitResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalCommit(request, response, rpcContext);
|
||||
} catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore,
|
||||
String.format("global commit request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onTransactionException(GlobalCommitRequest request, GlobalCommitResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
@Override
|
||||
public GlobalCommitResponse handle(GlobalCommitRequest request, final RpcContext rpcContext) {
|
||||
GlobalCommitResponse response = new GlobalCommitResponse();
|
||||
response.setGlobalStatus(GlobalStatus.Committing);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalCommitRequest, GlobalCommitResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalCommitRequest request, GlobalCommitResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalCommit(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"global commit request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(GlobalCommitRequest request, GlobalCommitResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
@Override
|
||||
public void onTransactionException(GlobalCommitRequest request, GlobalCommitResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(GlobalCommitRequest request, GlobalCommitResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global commit.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
/**
|
||||
* Do global commit.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalCommit(GlobalCommitRequest request, GlobalCommitResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalRollbackResponse handle(GlobalRollbackRequest request, final RpcContext rpcContext) {
|
||||
GlobalRollbackResponse response = new GlobalRollbackResponse();
|
||||
response.setGlobalStatus(GlobalStatus.Rollbacking);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalRollbackRequest, GlobalRollbackResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalRollbackRequest request, GlobalRollbackResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalRollback(request, response, rpcContext);
|
||||
} catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String
|
||||
.format("global rollback request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public GlobalRollbackResponse handle(GlobalRollbackRequest request, final RpcContext rpcContext) {
|
||||
GlobalRollbackResponse response = new GlobalRollbackResponse();
|
||||
response.setGlobalStatus(GlobalStatus.Rollbacking);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalRollbackRequest, GlobalRollbackResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalRollbackRequest request, GlobalRollbackResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalRollback(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"global rollback request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionException(GlobalRollbackRequest request, GlobalRollbackResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
// may be appears StoreException outer layer method catch
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
@Override
|
||||
public void onTransactionException(GlobalRollbackRequest request, GlobalRollbackResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
// may be appears StoreException outer layer method catch
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(GlobalRollbackRequest request, GlobalRollbackResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
// may be appears StoreException outer layer method catch
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
@Override
|
||||
public void onException(GlobalRollbackRequest request, GlobalRollbackResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
// may be appears StoreException outer layer method catch
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global rollback.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalRollback(GlobalRollbackRequest request, GlobalRollbackResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
/**
|
||||
* Do global rollback.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalRollback(GlobalRollbackRequest request, GlobalRollbackResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public BranchRegisterResponse handle(BranchRegisterRequest request, final RpcContext rpcContext) {
|
||||
BranchRegisterResponse response = new BranchRegisterResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<BranchRegisterRequest, BranchRegisterResponse>() {
|
||||
@Override
|
||||
public void execute(BranchRegisterRequest request, BranchRegisterResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doBranchRegister(request, response, rpcContext);
|
||||
} catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String
|
||||
.format("branch register request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
@Override
|
||||
public BranchRegisterResponse handle(BranchRegisterRequest request, final RpcContext rpcContext) {
|
||||
BranchRegisterResponse response = new BranchRegisterResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<BranchRegisterRequest, BranchRegisterResponse>() {
|
||||
@Override
|
||||
public void execute(BranchRegisterRequest request, BranchRegisterResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doBranchRegister(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"branch register request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do branch register.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
/**
|
||||
* Do branch register.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doBranchRegister(BranchRegisterRequest request, BranchRegisterResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public BranchReportResponse handle(BranchReportRequest request, final RpcContext rpcContext) {
|
||||
BranchReportResponse response = new BranchReportResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<BranchReportRequest, BranchReportResponse>() {
|
||||
@Override
|
||||
public void execute(BranchReportRequest request, BranchReportResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doBranchReport(request, response, rpcContext);
|
||||
} catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String
|
||||
.format("branch report request failed. xid=%s, branchId=%s, msg=%s", request.getXid(),
|
||||
request.getBranchId(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
@Override
|
||||
public BranchReportResponse handle(BranchReportRequest request, final RpcContext rpcContext) {
|
||||
BranchReportResponse response = new BranchReportResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<BranchReportRequest, BranchReportResponse>() {
|
||||
@Override
|
||||
public void execute(BranchReportRequest request, BranchReportResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doBranchReport(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore,
|
||||
String.format("branch report request failed. xid=%s, branchId=%s, msg=%s", request.getXid(),
|
||||
request.getBranchId(), e.getMessage()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do branch report.
|
||||
*
|
||||
* @param request the request
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doBranchReport(BranchReportRequest request, BranchReportResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
/**
|
||||
* Do branch report.
|
||||
* @param request the request
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doBranchReport(BranchReportRequest request, BranchReportResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalLockQueryResponse handle(GlobalLockQueryRequest request, final RpcContext rpcContext) {
|
||||
GlobalLockQueryResponse response = new GlobalLockQueryResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalLockQueryRequest, GlobalLockQueryResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalLockQueryRequest request, GlobalLockQueryResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doLockCheck(request, response, rpcContext);
|
||||
} catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String
|
||||
.format("global lock query request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
@Override
|
||||
public GlobalLockQueryResponse handle(GlobalLockQueryRequest request, final RpcContext rpcContext) {
|
||||
GlobalLockQueryResponse response = new GlobalLockQueryResponse();
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalLockQueryRequest, GlobalLockQueryResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalLockQueryRequest request, GlobalLockQueryResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doLockCheck(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"global lock query request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do lock check.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
/**
|
||||
* Do lock check.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doLockCheck(GlobalLockQueryRequest request, GlobalLockQueryResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalStatusResponse handle(GlobalStatusRequest request, final RpcContext rpcContext) {
|
||||
GlobalStatusResponse response = new GlobalStatusResponse();
|
||||
response.setGlobalStatus(GlobalStatus.UnKnown);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalStatusRequest, GlobalStatusResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalStatusRequest request, GlobalStatusResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalStatus(request, response, rpcContext);
|
||||
} catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore,
|
||||
String.format("global status request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public GlobalStatusResponse handle(GlobalStatusRequest request, final RpcContext rpcContext) {
|
||||
GlobalStatusResponse response = new GlobalStatusResponse();
|
||||
response.setGlobalStatus(GlobalStatus.UnKnown);
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalStatusRequest, GlobalStatusResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalStatusRequest request, GlobalStatusResponse response)
|
||||
throws TransactionException {
|
||||
try {
|
||||
doGlobalStatus(request, response, rpcContext);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw new TransactionException(TransactionExceptionCode.FailedStore, String.format(
|
||||
"global status request failed. xid=%s, msg=%s", request.getXid(), e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTransactionException(GlobalStatusRequest request, GlobalStatusResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
@Override
|
||||
public void onTransactionException(GlobalStatusRequest request, GlobalStatusResponse response,
|
||||
TransactionException tex) {
|
||||
super.onTransactionException(request, response, tex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(GlobalStatusRequest request, GlobalStatusResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
@Override
|
||||
public void onException(GlobalStatusRequest request, GlobalStatusResponse response, Exception rex) {
|
||||
super.onException(request, response, rex);
|
||||
checkTransactionStatus(request, response);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global status.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalStatus(GlobalStatusRequest request, GlobalStatusResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
/**
|
||||
* Do global status.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalStatus(GlobalStatusRequest request, GlobalStatusResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
@Override
|
||||
public GlobalReportResponse handle(GlobalReportRequest request, final RpcContext rpcContext) {
|
||||
GlobalReportResponse response = new GlobalReportResponse();
|
||||
response.setGlobalStatus(request.getGlobalStatus());
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalReportRequest, GlobalReportResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalReportRequest request, GlobalReportResponse response)
|
||||
throws TransactionException {
|
||||
doGlobalReport(request, response, rpcContext);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
@Override
|
||||
public GlobalReportResponse handle(GlobalReportRequest request, final RpcContext rpcContext) {
|
||||
GlobalReportResponse response = new GlobalReportResponse();
|
||||
response.setGlobalStatus(request.getGlobalStatus());
|
||||
exceptionHandleTemplate(new AbstractCallback<GlobalReportRequest, GlobalReportResponse>() {
|
||||
@Override
|
||||
public void execute(GlobalReportRequest request, GlobalReportResponse response)
|
||||
throws TransactionException {
|
||||
doGlobalReport(request, response, rpcContext);
|
||||
}
|
||||
}, request, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do global report.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalReport(GlobalReportRequest request, GlobalReportResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
/**
|
||||
* Do global report.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param rpcContext the rpc context
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
protected abstract void doGlobalReport(GlobalReportRequest request, GlobalReportResponse response,
|
||||
RpcContext rpcContext) throws TransactionException;
|
||||
|
||||
private void checkTransactionStatus(AbstractGlobalEndRequest request, AbstractGlobalEndResponse response) {
|
||||
try {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(request.getXid(), false);
|
||||
if (globalSession != null) {
|
||||
response.setGlobalStatus(globalSession.getStatus());
|
||||
}
|
||||
else {
|
||||
response.setGlobalStatus(GlobalStatus.Finished);
|
||||
}
|
||||
}
|
||||
catch (Exception exx) {
|
||||
LOGGER.error("check transaction status error,{}]", exx.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTransactionStatus(AbstractGlobalEndRequest request, AbstractGlobalEndResponse response) {
|
||||
try {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(request.getXid(), false);
|
||||
if (globalSession != null) {
|
||||
response.setGlobalStatus(globalSession.getStatus());
|
||||
} else {
|
||||
response.setGlobalStatus(GlobalStatus.Finished);
|
||||
}
|
||||
} catch (Exception exx) {
|
||||
LOGGER.error("check transaction status error,{}]", exx.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
+146
-146
@@ -33,168 +33,168 @@ import static io.seata.config.ConfigurationFactory.ENV_PROPERTY_KEY;
|
||||
*/
|
||||
public class ParameterParser {
|
||||
|
||||
private static final String PROGRAM_NAME
|
||||
= "sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows)";
|
||||
private static final String PROGRAM_NAME = "sh seata-server.sh(for linux and mac) or cmd seata-server.bat(for windows)";
|
||||
|
||||
private static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
private static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
|
||||
@Parameter(names = "--help", help = true)
|
||||
private boolean help;
|
||||
@Parameter(names = {"--host", "-h"}, description = "The ip to register to registry center.", order = 1)
|
||||
private String host;
|
||||
@Parameter(names = {"--port", "-p"}, description = "The port to listen.", order = 2)
|
||||
private int port;
|
||||
@Parameter(names = {"--storeMode", "-m"}, description = "log store mode : file, db, redis", order = 3)
|
||||
private String storeMode;
|
||||
@Parameter(names = {"--serverNode", "-n"}, description = "server node id, such as 1, 2, 3.it will be generated according to the snowflake by default", order = 4)
|
||||
private Long serverNode;
|
||||
@Parameter(names = {"--seataEnv", "-e"}, description = "The name used for multi-configuration isolation.",
|
||||
order = 5)
|
||||
private String seataEnv;
|
||||
@Parameter(names = {"--sessionStoreMode", "-ssm"}, description = "session log store mode : file, db, redis",
|
||||
order = 6)
|
||||
private String sessionStoreMode;
|
||||
@Parameter(names = {"--lockStoreMode", "-lsm"}, description = "lock log store mode : file, db, redis", order = 7)
|
||||
private String lockStoreMode;
|
||||
@Parameter(names = "--help", help = true)
|
||||
private boolean help;
|
||||
|
||||
/**
|
||||
* Instantiates a new Parameter parser.
|
||||
*
|
||||
* @param args the args
|
||||
*/
|
||||
public ParameterParser(String... args) {
|
||||
this.init(args);
|
||||
}
|
||||
@Parameter(names = { "--host", "-h" }, description = "The ip to register to registry center.", order = 1)
|
||||
private String host;
|
||||
|
||||
/**
|
||||
* startup args > docker env
|
||||
* @param args
|
||||
*/
|
||||
private void init(String[] args) {
|
||||
try {
|
||||
getCommandParameters(args);
|
||||
getEnvParameters();
|
||||
if (StringUtils.isNotBlank(seataEnv)) {
|
||||
System.setProperty(ENV_PROPERTY_KEY, seataEnv);
|
||||
}
|
||||
StoreConfig.setStartupParameter(storeMode, sessionStoreMode, lockStoreMode);
|
||||
} catch (ParameterException e) {
|
||||
printError(e);
|
||||
}
|
||||
@Parameter(names = { "--port", "-p" }, description = "The port to listen.", order = 2)
|
||||
private int port;
|
||||
|
||||
}
|
||||
@Parameter(names = { "--storeMode", "-m" }, description = "log store mode : file, db, redis", order = 3)
|
||||
private String storeMode;
|
||||
|
||||
private void getCommandParameters(String[] args) {
|
||||
JCommander jCommander = JCommander.newBuilder().addObject(this).build();
|
||||
jCommander.parse(args);
|
||||
if (help) {
|
||||
jCommander.setProgramName(PROGRAM_NAME);
|
||||
jCommander.usage();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
@Parameter(names = { "--serverNode", "-n" },
|
||||
description = "server node id, such as 1, 2, 3.it will be generated according to the snowflake by default",
|
||||
order = 4)
|
||||
private Long serverNode;
|
||||
|
||||
private void getEnvParameters() {
|
||||
if (StringUtils.isBlank(seataEnv)) {
|
||||
seataEnv = ContainerHelper.getEnv();
|
||||
}
|
||||
if (StringUtils.isBlank(host)) {
|
||||
host = ContainerHelper.getHost();
|
||||
}
|
||||
if (port == 0) {
|
||||
port = ContainerHelper.getPort();
|
||||
}
|
||||
if (serverNode == null) {
|
||||
serverNode = ContainerHelper.getServerNode();
|
||||
}
|
||||
}
|
||||
@Parameter(names = { "--seataEnv", "-e" }, description = "The name used for multi-configuration isolation.",
|
||||
order = 5)
|
||||
private String seataEnv;
|
||||
|
||||
private void printError(ParameterException e) {
|
||||
System.err.println("Option error " + e.getMessage());
|
||||
e.getJCommander().setProgramName(PROGRAM_NAME);
|
||||
e.usage();
|
||||
System.exit(0);
|
||||
}
|
||||
@Parameter(names = { "--sessionStoreMode", "-ssm" }, description = "session log store mode : file, db, redis",
|
||||
order = 6)
|
||||
private String sessionStoreMode;
|
||||
|
||||
/**
|
||||
* Gets host.
|
||||
*
|
||||
* @return the host
|
||||
*/
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
@Parameter(names = { "--lockStoreMode", "-lsm" }, description = "lock log store mode : file, db, redis", order = 7)
|
||||
private String lockStoreMode;
|
||||
|
||||
/**
|
||||
* Gets port.
|
||||
*
|
||||
* @return the port
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Parameter parser.
|
||||
* @param args the args
|
||||
*/
|
||||
public ParameterParser(String... args) {
|
||||
this.init(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets store mode.
|
||||
*
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getStoreMode() {
|
||||
return storeMode;
|
||||
}
|
||||
/**
|
||||
* startup args > docker env
|
||||
* @param args
|
||||
*/
|
||||
private void init(String[] args) {
|
||||
try {
|
||||
getCommandParameters(args);
|
||||
getEnvParameters();
|
||||
if (StringUtils.isNotBlank(seataEnv)) {
|
||||
System.setProperty(ENV_PROPERTY_KEY, seataEnv);
|
||||
}
|
||||
StoreConfig.setStartupParameter(storeMode, sessionStoreMode, lockStoreMode);
|
||||
}
|
||||
catch (ParameterException e) {
|
||||
printError(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock store mode.
|
||||
*
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getLockStoreMode() {
|
||||
return lockStoreMode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets session store mode.
|
||||
*
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getSessionStoreMode() {
|
||||
return sessionStoreMode;
|
||||
}
|
||||
private void getCommandParameters(String[] args) {
|
||||
JCommander jCommander = JCommander.newBuilder().addObject(this).build();
|
||||
jCommander.parse(args);
|
||||
if (help) {
|
||||
jCommander.setProgramName(PROGRAM_NAME);
|
||||
jCommander.usage();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is help boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isHelp() {
|
||||
return help;
|
||||
}
|
||||
private void getEnvParameters() {
|
||||
if (StringUtils.isBlank(seataEnv)) {
|
||||
seataEnv = ContainerHelper.getEnv();
|
||||
}
|
||||
if (StringUtils.isBlank(host)) {
|
||||
host = ContainerHelper.getHost();
|
||||
}
|
||||
if (port == 0) {
|
||||
port = ContainerHelper.getPort();
|
||||
}
|
||||
if (serverNode == null) {
|
||||
serverNode = ContainerHelper.getServerNode();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets server node.
|
||||
*
|
||||
* @return the server node
|
||||
*/
|
||||
public Long getServerNode() {
|
||||
return serverNode;
|
||||
}
|
||||
private void printError(ParameterException e) {
|
||||
System.err.println("Option error " + e.getMessage());
|
||||
e.getJCommander().setProgramName(PROGRAM_NAME);
|
||||
e.usage();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets seata env
|
||||
*
|
||||
* @return the name used for multi-configuration isolation.
|
||||
*/
|
||||
public String getSeataEnv() {
|
||||
return seataEnv;
|
||||
}
|
||||
/**
|
||||
* Gets host.
|
||||
* @return the host
|
||||
*/
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up.
|
||||
*/
|
||||
public void cleanUp() {
|
||||
if (null != System.getProperty(ENV_PROPERTY_KEY)) {
|
||||
System.clearProperty(ENV_PROPERTY_KEY);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets port.
|
||||
* @return the port
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets store mode.
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getStoreMode() {
|
||||
return storeMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock store mode.
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getLockStoreMode() {
|
||||
return lockStoreMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets session store mode.
|
||||
* @return the store mode
|
||||
*/
|
||||
public String getSessionStoreMode() {
|
||||
return sessionStoreMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is help boolean.
|
||||
* @return the boolean
|
||||
*/
|
||||
public boolean isHelp() {
|
||||
return help;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets server node.
|
||||
* @return the server node
|
||||
*/
|
||||
public Long getServerNode() {
|
||||
return serverNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets seata env
|
||||
* @return the name used for multi-configuration isolation.
|
||||
*/
|
||||
public String getSeataEnv() {
|
||||
return seataEnv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up.
|
||||
*/
|
||||
public void cleanUp() {
|
||||
if (null != System.getProperty(ENV_PROPERTY_KEY)) {
|
||||
System.clearProperty(ENV_PROPERTY_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,50 +40,55 @@ import static io.seata.spring.boot.autoconfigure.StarterConstants.REGISTRY_PREFE
|
||||
* @author slievrly
|
||||
*/
|
||||
public class Server {
|
||||
/**
|
||||
* The entry point of application.
|
||||
*
|
||||
* @param args the input arguments
|
||||
*/
|
||||
public static void start(String[] args) {
|
||||
//initialize the parameter parser
|
||||
//Note that the parameter parser should always be the first line to execute.
|
||||
//Because, here we need to parse the parameters needed for startup.
|
||||
ParameterParser parameterParser = new ParameterParser(args);
|
||||
|
||||
//initialize the metrics
|
||||
MetricsManager.get().init();
|
||||
/**
|
||||
* The entry point of application.
|
||||
* @param args the input arguments
|
||||
*/
|
||||
public static void start(String[] args) {
|
||||
// initialize the parameter parser
|
||||
// Note that the parameter parser should always be the first line to execute.
|
||||
// Because, here we need to parse the parameters needed for startup.
|
||||
ParameterParser parameterParser = new ParameterParser(args);
|
||||
|
||||
ThreadPoolExecutor workingThreads = new ThreadPoolExecutor(NettyServerConfig.getMinServerPoolSize(),
|
||||
NettyServerConfig.getMaxServerPoolSize(), NettyServerConfig.getKeepAliveTime(), TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<>(NettyServerConfig.getMaxTaskQueueSize()),
|
||||
new NamedThreadFactory("ServerHandlerThread", NettyServerConfig.getMaxServerPoolSize()), new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
// initialize the metrics
|
||||
MetricsManager.get().init();
|
||||
|
||||
//127.0.0.1 and 0.0.0.0 are not valid here.
|
||||
if (NetUtil.isValidIp(parameterParser.getHost(), false)) {
|
||||
XID.setIpAddress(parameterParser.getHost());
|
||||
} else {
|
||||
String preferredNetworks = ConfigurationFactory.getInstance().getConfig(REGISTRY_PREFERED_NETWORKS);
|
||||
if (StringUtils.isNotBlank(preferredNetworks)) {
|
||||
XID.setIpAddress(NetUtil.getLocalIp(preferredNetworks.split(REGEX_SPLIT_CHAR)));
|
||||
} else {
|
||||
XID.setIpAddress(NetUtil.getLocalIp());
|
||||
}
|
||||
}
|
||||
ThreadPoolExecutor workingThreads = new ThreadPoolExecutor(NettyServerConfig.getMinServerPoolSize(),
|
||||
NettyServerConfig.getMaxServerPoolSize(), NettyServerConfig.getKeepAliveTime(), TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<>(NettyServerConfig.getMaxTaskQueueSize()),
|
||||
new NamedThreadFactory("ServerHandlerThread", NettyServerConfig.getMaxServerPoolSize()),
|
||||
new ThreadPoolExecutor.CallerRunsPolicy());
|
||||
|
||||
NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads);
|
||||
XID.setPort(nettyRemotingServer.getListenPort());
|
||||
UUIDGenerator.init(parameterParser.getServerNode());
|
||||
//log store mode : file, db, redis
|
||||
SessionHolder.init();
|
||||
LockerManagerFactory.init();
|
||||
DefaultCoordinator coordinator = DefaultCoordinator.getInstance(nettyRemotingServer);
|
||||
coordinator.init();
|
||||
nettyRemotingServer.setHandler(coordinator);
|
||||
// 127.0.0.1 and 0.0.0.0 are not valid here.
|
||||
if (NetUtil.isValidIp(parameterParser.getHost(), false)) {
|
||||
XID.setIpAddress(parameterParser.getHost());
|
||||
}
|
||||
else {
|
||||
String preferredNetworks = ConfigurationFactory.getInstance().getConfig(REGISTRY_PREFERED_NETWORKS);
|
||||
if (StringUtils.isNotBlank(preferredNetworks)) {
|
||||
XID.setIpAddress(NetUtil.getLocalIp(preferredNetworks.split(REGEX_SPLIT_CHAR)));
|
||||
}
|
||||
else {
|
||||
XID.setIpAddress(NetUtil.getLocalIp());
|
||||
}
|
||||
}
|
||||
|
||||
// let ServerRunner do destroy instead ShutdownHook, see https://github.com/seata/seata/issues/4028
|
||||
ServerRunner.addDisposable(coordinator);
|
||||
NettyRemotingServer nettyRemotingServer = new NettyRemotingServer(workingThreads);
|
||||
XID.setPort(nettyRemotingServer.getListenPort());
|
||||
UUIDGenerator.init(parameterParser.getServerNode());
|
||||
// log store mode : file, db, redis
|
||||
SessionHolder.init();
|
||||
LockerManagerFactory.init();
|
||||
DefaultCoordinator coordinator = DefaultCoordinator.getInstance(nettyRemotingServer);
|
||||
coordinator.init();
|
||||
nettyRemotingServer.setHandler(coordinator);
|
||||
|
||||
// let ServerRunner do destroy instead ShutdownHook, see
|
||||
// https://github.com/seata/seata/issues/4028
|
||||
ServerRunner.addDisposable(coordinator);
|
||||
|
||||
nettyRemotingServer.init();
|
||||
}
|
||||
|
||||
nettyRemotingServer.init();
|
||||
}
|
||||
}
|
||||
@@ -23,10 +23,12 @@ import java.io.IOException;
|
||||
/**
|
||||
* @author spilledyear@outlook.com
|
||||
*/
|
||||
@SpringBootApplication(scanBasePackages = {"io.seata"})
|
||||
@SpringBootApplication(scanBasePackages = { "io.seata" })
|
||||
public class ServerApplication {
|
||||
public static void main(String[] args) throws IOException {
|
||||
// run the spring-boot application
|
||||
SpringApplication.run(ServerApplication.class, args);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
// run the spring-boot application
|
||||
SpringApplication.run(ServerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+75
-74
@@ -40,89 +40,90 @@ import static io.seata.core.constants.ConfigurationKeys.*;
|
||||
*/
|
||||
public class ServerApplicationListener implements GenericApplicationListener {
|
||||
|
||||
@Override
|
||||
public boolean supportsEventType(ResolvableType eventType) {
|
||||
return eventType.getRawClass() != null
|
||||
&& ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType.getRawClass());
|
||||
}
|
||||
@Override
|
||||
public boolean supportsEventType(ResolvableType eventType) {
|
||||
return eventType.getRawClass() != null
|
||||
&& ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType.getRawClass());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (!(event instanceof ApplicationEnvironmentPreparedEvent)) {
|
||||
return;
|
||||
}
|
||||
ApplicationEnvironmentPreparedEvent environmentPreparedEvent = (ApplicationEnvironmentPreparedEvent)event;
|
||||
ConfigurableEnvironment environment = environmentPreparedEvent.getEnvironment();
|
||||
ObjectHolder.INSTANCE.setObject(OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT, environment);
|
||||
SeataCoreEnvironmentPostProcessor.init();
|
||||
SeataServerEnvironmentPostProcessor.init();
|
||||
// Load by priority
|
||||
System.setProperty("sessionMode", StoreConfig.getSessionMode().getName());
|
||||
System.setProperty("lockMode", StoreConfig.getLockMode().getName());
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (!(event instanceof ApplicationEnvironmentPreparedEvent)) {
|
||||
return;
|
||||
}
|
||||
ApplicationEnvironmentPreparedEvent environmentPreparedEvent = (ApplicationEnvironmentPreparedEvent) event;
|
||||
ConfigurableEnvironment environment = environmentPreparedEvent.getEnvironment();
|
||||
ObjectHolder.INSTANCE.setObject(OBJECT_KEY_SPRING_CONFIGURABLE_ENVIRONMENT, environment);
|
||||
SeataCoreEnvironmentPostProcessor.init();
|
||||
SeataServerEnvironmentPostProcessor.init();
|
||||
// Load by priority
|
||||
System.setProperty("sessionMode", StoreConfig.getSessionMode().getName());
|
||||
System.setProperty("lockMode", StoreConfig.getLockMode().getName());
|
||||
|
||||
String[] args = environmentPreparedEvent.getArgs();
|
||||
String[] args = environmentPreparedEvent.getArgs();
|
||||
|
||||
// port: -p > -D > env > yml > default
|
||||
// port: -p > -D > env > yml > default
|
||||
|
||||
//-p 8091
|
||||
if (args != null && args.length >= 2) {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
if ("-p".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
setTargetPort(environment, args[i + 1], true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// -p 8091
|
||||
if (args != null && args.length >= 2) {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
if ("-p".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
setTargetPort(environment, args[i + 1], true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -Dserver.servicePort=8091
|
||||
String dPort = environment.getProperty(SERVER_SERVICE_PORT_CAMEL, String.class);
|
||||
if (StringUtils.isNotBlank(dPort)) {
|
||||
setTargetPort(environment, dPort, true);
|
||||
return;
|
||||
}
|
||||
// -Dserver.servicePort=8091
|
||||
String dPort = environment.getProperty(SERVER_SERVICE_PORT_CAMEL, String.class);
|
||||
if (StringUtils.isNotBlank(dPort)) {
|
||||
setTargetPort(environment, dPort, true);
|
||||
return;
|
||||
}
|
||||
|
||||
//docker -e SEATA_PORT=8091
|
||||
String envPort = environment.getProperty(ENV_SEATA_PORT_KEY, String.class);
|
||||
if (StringUtils.isNotBlank(envPort)) {
|
||||
setTargetPort(environment, envPort, true);
|
||||
return;
|
||||
}
|
||||
// docker -e SEATA_PORT=8091
|
||||
String envPort = environment.getProperty(ENV_SEATA_PORT_KEY, String.class);
|
||||
if (StringUtils.isNotBlank(envPort)) {
|
||||
setTargetPort(environment, envPort, true);
|
||||
return;
|
||||
}
|
||||
|
||||
//yml properties server.service-port=8091
|
||||
String configPort = environment.getProperty(SERVER_SERVICE_PORT_CONFIG, String.class);
|
||||
if (StringUtils.isNotBlank(configPort)) {
|
||||
setTargetPort(environment, configPort, false);
|
||||
return;
|
||||
}
|
||||
// yml properties server.service-port=8091
|
||||
String configPort = environment.getProperty(SERVER_SERVICE_PORT_CONFIG, String.class);
|
||||
if (StringUtils.isNotBlank(configPort)) {
|
||||
setTargetPort(environment, configPort, false);
|
||||
return;
|
||||
}
|
||||
|
||||
// server.port=7091
|
||||
String serverPort = environment.getProperty("server.port", String.class);
|
||||
if (StringUtils.isBlank(serverPort)) {
|
||||
serverPort = "8080";
|
||||
}
|
||||
String servicePort = String.valueOf(Integer.parseInt(serverPort) + SERVICE_OFFSET_SPRING_BOOT);
|
||||
setTargetPort(environment, servicePort, true);
|
||||
}
|
||||
// server.port=7091
|
||||
String serverPort = environment.getProperty("server.port", String.class);
|
||||
if (StringUtils.isBlank(serverPort)) {
|
||||
serverPort = "8080";
|
||||
}
|
||||
String servicePort = String.valueOf(Integer.parseInt(serverPort) + SERVICE_OFFSET_SPRING_BOOT);
|
||||
setTargetPort(environment, servicePort, true);
|
||||
}
|
||||
|
||||
private void setTargetPort(ConfigurableEnvironment environment, String port, boolean needAddPropertySource) {
|
||||
// get rpc port first, use to logback-spring.xml, @see the class named `SystemPropertyLoggerContextListener`
|
||||
System.setProperty(SERVER_SERVICE_PORT_CAMEL, port);
|
||||
private void setTargetPort(ConfigurableEnvironment environment, String port, boolean needAddPropertySource) {
|
||||
// get rpc port first, use to logback-spring.xml, @see the class named
|
||||
// `SystemPropertyLoggerContextListener`
|
||||
System.setProperty(SERVER_SERVICE_PORT_CAMEL, port);
|
||||
|
||||
if (needAddPropertySource) {
|
||||
// add property source to the first position
|
||||
Properties pro = new Properties();
|
||||
pro.setProperty(SERVER_SERVICE_PORT_CONFIG, port);
|
||||
environment.getPropertySources().addFirst(new PropertiesPropertySource("serverProperties", pro));
|
||||
}
|
||||
}
|
||||
if (needAddPropertySource) {
|
||||
// add property source to the first position
|
||||
Properties pro = new Properties();
|
||||
pro.setProperty(SERVER_SERVICE_PORT_CONFIG, port);
|
||||
environment.getPropertySources().addFirst(new PropertiesPropertySource("serverProperties", pro));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* higher than LoggingApplicationListener
|
||||
* @return the order
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return LoggingApplicationListener.DEFAULT_ORDER - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* higher than LoggingApplicationListener
|
||||
*
|
||||
* @return the order
|
||||
*/
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return LoggingApplicationListener.DEFAULT_ORDER - 1;
|
||||
}
|
||||
}
|
||||
@@ -25,57 +25,57 @@ import org.springframework.stereotype.Component;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* @author spilledyear@outlook.com
|
||||
*/
|
||||
@Component
|
||||
public class ServerRunner implements CommandLineRunner, DisposableBean {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ServerRunner.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ServerRunner.class);
|
||||
|
||||
private boolean started = Boolean.FALSE;
|
||||
private boolean started = Boolean.FALSE;
|
||||
|
||||
private static final List<Disposable> DISPOSABLE_LIST = new CopyOnWriteArrayList<>();
|
||||
private static final List<Disposable> DISPOSABLE_LIST = new CopyOnWriteArrayList<>();
|
||||
|
||||
public static void addDisposable(Disposable disposable) {
|
||||
DISPOSABLE_LIST.add(disposable);
|
||||
}
|
||||
public static void addDisposable(Disposable disposable) {
|
||||
DISPOSABLE_LIST.add(disposable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
Server.start(args);
|
||||
started = true;
|
||||
@Override
|
||||
public void run(String... args) {
|
||||
try {
|
||||
long start = System.currentTimeMillis();
|
||||
Server.start(args);
|
||||
started = true;
|
||||
|
||||
long cost = System.currentTimeMillis() - start;
|
||||
LOGGER.info("seata server started in {} millSeconds", cost);
|
||||
} catch (Throwable e) {
|
||||
started = Boolean.FALSE;
|
||||
LOGGER.error("seata server start error: {} ", e.getMessage(), e);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
long cost = System.currentTimeMillis() - start;
|
||||
LOGGER.info("seata server started in {} millSeconds", cost);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
started = Boolean.FALSE;
|
||||
LOGGER.error("seata server start error: {} ", e.getMessage(), e);
|
||||
System.exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean started() {
|
||||
return started;
|
||||
}
|
||||
|
||||
public boolean started() {
|
||||
return started;
|
||||
}
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("destoryAll starting");
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("destoryAll starting");
|
||||
}
|
||||
for (Disposable disposable : DISPOSABLE_LIST) {
|
||||
disposable.destroy();
|
||||
}
|
||||
|
||||
for (Disposable disposable : DISPOSABLE_LIST) {
|
||||
disposable.destroy();
|
||||
}
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("destoryAll finish");
|
||||
}
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("destoryAll finish");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,28 +24,29 @@ import io.seata.common.util.IdWorker;
|
||||
*/
|
||||
public class UUIDGenerator {
|
||||
|
||||
private static volatile IdWorker idWorker;
|
||||
private static volatile IdWorker idWorker;
|
||||
|
||||
/**
|
||||
* generate UUID using snowflake algorithm
|
||||
* @return UUID
|
||||
*/
|
||||
public static long generateUUID() {
|
||||
if (idWorker == null) {
|
||||
synchronized (UUIDGenerator.class) {
|
||||
if (idWorker == null) {
|
||||
init(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return idWorker.nextId();
|
||||
}
|
||||
/**
|
||||
* generate UUID using snowflake algorithm
|
||||
* @return UUID
|
||||
*/
|
||||
public static long generateUUID() {
|
||||
if (idWorker == null) {
|
||||
synchronized (UUIDGenerator.class) {
|
||||
if (idWorker == null) {
|
||||
init(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
return idWorker.nextId();
|
||||
}
|
||||
|
||||
/**
|
||||
* init IdWorker
|
||||
* @param serverNode the server node id, consider as machine id in snowflake
|
||||
*/
|
||||
public static void init(Long serverNode) {
|
||||
idWorker = new IdWorker(serverNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* init IdWorker
|
||||
* @param serverNode the server node id, consider as machine id in snowflake
|
||||
*/
|
||||
public static void init(Long serverNode) {
|
||||
idWorker = new IdWorker(serverNode);
|
||||
}
|
||||
}
|
||||
+19
-18
@@ -28,26 +28,27 @@ import static io.seata.common.DefaultValues.DEFAULT_SERVER_ENABLE_CHECK_AUTH;
|
||||
*/
|
||||
public abstract class AbstractCheckAuthHandler implements RegisterCheckAuthHandler {
|
||||
|
||||
private static final Boolean ENABLE_CHECK_AUTH = ConfigurationFactory.getInstance().getBoolean(
|
||||
ConfigurationKeys.SERVER_ENABLE_CHECK_AUTH, DEFAULT_SERVER_ENABLE_CHECK_AUTH);
|
||||
private static final Boolean ENABLE_CHECK_AUTH = ConfigurationFactory.getInstance()
|
||||
.getBoolean(ConfigurationKeys.SERVER_ENABLE_CHECK_AUTH, DEFAULT_SERVER_ENABLE_CHECK_AUTH);
|
||||
|
||||
@Override
|
||||
public boolean regTransactionManagerCheckAuth(RegisterTMRequest request) {
|
||||
if (!ENABLE_CHECK_AUTH) {
|
||||
return true;
|
||||
}
|
||||
return doRegTransactionManagerCheck(request);
|
||||
}
|
||||
@Override
|
||||
public boolean regTransactionManagerCheckAuth(RegisterTMRequest request) {
|
||||
if (!ENABLE_CHECK_AUTH) {
|
||||
return true;
|
||||
}
|
||||
return doRegTransactionManagerCheck(request);
|
||||
}
|
||||
|
||||
public abstract boolean doRegTransactionManagerCheck(RegisterTMRequest request);
|
||||
public abstract boolean doRegTransactionManagerCheck(RegisterTMRequest request);
|
||||
|
||||
@Override
|
||||
public boolean regResourceManagerCheckAuth(RegisterRMRequest request) {
|
||||
if (!ENABLE_CHECK_AUTH) {
|
||||
return true;
|
||||
}
|
||||
return doRegResourceManagerCheck(request);
|
||||
}
|
||||
@Override
|
||||
public boolean regResourceManagerCheckAuth(RegisterRMRequest request) {
|
||||
if (!ENABLE_CHECK_AUTH) {
|
||||
return true;
|
||||
}
|
||||
return doRegResourceManagerCheck(request);
|
||||
}
|
||||
|
||||
public abstract boolean doRegResourceManagerCheck(RegisterRMRequest request);
|
||||
|
||||
public abstract boolean doRegResourceManagerCheck(RegisterRMRequest request);
|
||||
}
|
||||
+9
-8
@@ -25,13 +25,14 @@ import io.seata.core.protocol.RegisterTMRequest;
|
||||
@LoadLevel(name = "defaultCheckAuthHandler", order = 100)
|
||||
public class DefaultCheckAuthHandler extends AbstractCheckAuthHandler {
|
||||
|
||||
@Override
|
||||
public boolean doRegTransactionManagerCheck(RegisterTMRequest request) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean doRegTransactionManagerCheck(RegisterTMRequest request) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doRegResourceManagerCheck(RegisterRMRequest request) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doRegResourceManagerCheck(RegisterRMRequest request) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -23,14 +23,14 @@ import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* Branch Session Controller
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("console/branchSession")
|
||||
public class BranchSessionController {
|
||||
|
||||
@Resource(type = BranchSessionService.class)
|
||||
private BranchSessionService branchSessionService;
|
||||
|
||||
@Resource(type = BranchSessionService.class)
|
||||
private BranchSessionService branchSessionService;
|
||||
|
||||
}
|
||||
+12
-12
@@ -26,26 +26,26 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* Global Lock Controller
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/console/globalLock")
|
||||
public class GlobalLockController {
|
||||
|
||||
@Resource(type = GlobalLockService.class)
|
||||
private GlobalLockService globalLockService;
|
||||
@Resource(type = GlobalLockService.class)
|
||||
private GlobalLockService globalLockService;
|
||||
|
||||
/**
|
||||
* Query locks by param
|
||||
* @param param the param
|
||||
* @return the list of GlobalLockVO
|
||||
*/
|
||||
@GetMapping("query")
|
||||
public PageResult<GlobalLockVO> query(@ModelAttribute GlobalLockParam param) {
|
||||
return globalLockService.query(param);
|
||||
}
|
||||
/**
|
||||
* Query locks by param
|
||||
* @param param the param
|
||||
* @return the list of GlobalLockVO
|
||||
*/
|
||||
@GetMapping("query")
|
||||
public PageResult<GlobalLockVO> query(@ModelAttribute GlobalLockParam param) {
|
||||
return globalLockService.query(param);
|
||||
}
|
||||
|
||||
}
|
||||
+12
-11
@@ -28,23 +28,24 @@ import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* Global Session Controller
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/console/globalSession")
|
||||
public class GlobalSessionController {
|
||||
|
||||
@Resource(type = GlobalSessionService.class)
|
||||
private GlobalSessionService globalSessionService;
|
||||
@Resource(type = GlobalSessionService.class)
|
||||
private GlobalSessionService globalSessionService;
|
||||
|
||||
/**
|
||||
* Query all globalSession
|
||||
* @param param param for query globalSession
|
||||
* @return the list of GlobalSessionVO
|
||||
*/
|
||||
@GetMapping("query")
|
||||
public PageResult<GlobalSessionVO> query(@ModelAttribute GlobalSessionParam param) {
|
||||
return globalSessionService.query(param);
|
||||
}
|
||||
/**
|
||||
* Query all globalSession
|
||||
* @param param param for query globalSession
|
||||
* @return the list of GlobalSessionVO
|
||||
*/
|
||||
@GetMapping("query")
|
||||
public PageResult<GlobalSessionVO> query(@ModelAttribute GlobalSessionParam param) {
|
||||
return globalSessionService.query(param);
|
||||
}
|
||||
|
||||
}
|
||||
+42
-39
@@ -51,51 +51,54 @@ import static io.seata.common.DefaultValues.DEFAULT_STORE_DB_BRANCH_TABLE;
|
||||
@ConditionalOnExpression("#{'db'.equals('${sessionMode}')}")
|
||||
public class BranchSessionDBServiceImpl implements BranchSessionService {
|
||||
|
||||
private String branchTable;
|
||||
private String branchTable;
|
||||
|
||||
private String dbType;
|
||||
private String dbType;
|
||||
|
||||
private DataSource dataSource;
|
||||
private DataSource dataSource;
|
||||
|
||||
public BranchSessionDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
branchTable = configuration.getConfig(ConfigurationKeys.STORE_DB_BRANCH_TABLE, DEFAULT_STORE_DB_BRANCH_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
public BranchSessionDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
branchTable = configuration.getConfig(ConfigurationKeys.STORE_DB_BRANCH_TABLE, DEFAULT_STORE_DB_BRANCH_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
if (StringUtils.isBlank(xid)) {
|
||||
throw new IllegalArgumentException("xid should not be blank");
|
||||
}
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
if (StringUtils.isBlank(xid)) {
|
||||
throw new IllegalArgumentException("xid should not be blank");
|
||||
}
|
||||
|
||||
String whereCondition = " where xid = ? ";
|
||||
String branchSessionSQL = LogStoreSqlsFactory.getLogStoreSqls(dbType).getAllBranchSessionSQL(branchTable, whereCondition);
|
||||
String whereCondition = " where xid = ? ";
|
||||
String branchSessionSQL = LogStoreSqlsFactory.getLogStoreSqls(dbType).getAllBranchSessionSQL(branchTable,
|
||||
whereCondition);
|
||||
|
||||
List<BranchSessionVO> list = new ArrayList<>();
|
||||
ResultSet rs = null;
|
||||
List<BranchSessionVO> list = new ArrayList<>();
|
||||
ResultSet rs = null;
|
||||
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(branchSessionSQL)) {
|
||||
ps.setObject(1, xid);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(BranchSessionVO.convert(rs));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
} finally {
|
||||
IOUtil.close(rs);
|
||||
}
|
||||
return PageResult.success(list, list.size(), 0, 0, 0);
|
||||
}
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(branchSessionSQL)) {
|
||||
ps.setObject(1, xid);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(BranchSessionVO.convert(rs));
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(rs);
|
||||
}
|
||||
return PageResult.success(list, list.size(), 0, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
+79
-78
@@ -42,7 +42,6 @@ import java.util.List;
|
||||
|
||||
import static io.seata.common.DefaultValues.DEFAULT_LOCK_DB_TABLE;
|
||||
|
||||
|
||||
/**
|
||||
* Global Lock DB ServiceImpl
|
||||
*
|
||||
@@ -54,92 +53,94 @@ import static io.seata.common.DefaultValues.DEFAULT_LOCK_DB_TABLE;
|
||||
@ConditionalOnExpression("#{'db'.equals('${lockMode}')}")
|
||||
public class GlobalLockDBServiceImpl implements GlobalLockService {
|
||||
|
||||
private String lockTable;
|
||||
private String lockTable;
|
||||
|
||||
private String dbType;
|
||||
private String dbType;
|
||||
|
||||
private DataSource dataSource;
|
||||
private DataSource dataSource;
|
||||
|
||||
public GlobalLockDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
lockTable = configuration.getConfig(ConfigurationKeys.LOCK_DB_TABLE, DEFAULT_LOCK_DB_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
public GlobalLockDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
lockTable = configuration.getConfig(ConfigurationKeys.LOCK_DB_TABLE, DEFAULT_LOCK_DB_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
PageUtil.checkParam(param.getPageNum(), param.getPageSize());
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
PageUtil.checkParam(param.getPageNum(), param.getPageSize());
|
||||
|
||||
List<Object> sqlParamList = new ArrayList<>();
|
||||
String whereCondition = this.getWhereConditionByParam(param, sqlParamList);
|
||||
List<Object> sqlParamList = new ArrayList<>();
|
||||
String whereCondition = this.getWhereConditionByParam(param, sqlParamList);
|
||||
|
||||
String sourceSql = LockStoreSqlFactory.getLogStoreSql(dbType).getAllLockSql(lockTable, whereCondition);
|
||||
String queryLockSql = PageUtil.pageSql(sourceSql, dbType, param.getPageNum(), param.getPageSize());
|
||||
String lockCountSql = PageUtil.countSql(sourceSql, dbType);
|
||||
String sourceSql = LockStoreSqlFactory.getLogStoreSql(dbType).getAllLockSql(lockTable, whereCondition);
|
||||
String queryLockSql = PageUtil.pageSql(sourceSql, dbType, param.getPageNum(), param.getPageSize());
|
||||
String lockCountSql = PageUtil.countSql(sourceSql, dbType);
|
||||
|
||||
List<GlobalLockVO> list = new ArrayList<>();
|
||||
int count = 0;
|
||||
List<GlobalLockVO> list = new ArrayList<>();
|
||||
int count = 0;
|
||||
|
||||
ResultSet rs = null;
|
||||
ResultSet countRs = null;
|
||||
ResultSet rs = null;
|
||||
ResultSet countRs = null;
|
||||
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(queryLockSql);
|
||||
PreparedStatement countPs = conn.prepareStatement(lockCountSql)) {
|
||||
PageUtil.setObject(ps, sqlParamList);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(GlobalLockVO.convert(rs));
|
||||
}
|
||||
PageUtil.setObject(countPs, sqlParamList);
|
||||
countRs = countPs.executeQuery();
|
||||
if (countRs.next()) {
|
||||
count = countRs.getInt(1);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
} finally {
|
||||
IOUtil.close(rs, countRs);
|
||||
}
|
||||
return PageResult.success(list, count, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(queryLockSql);
|
||||
PreparedStatement countPs = conn.prepareStatement(lockCountSql)) {
|
||||
PageUtil.setObject(ps, sqlParamList);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(GlobalLockVO.convert(rs));
|
||||
}
|
||||
PageUtil.setObject(countPs, sqlParamList);
|
||||
countRs = countPs.executeQuery();
|
||||
if (countRs.next()) {
|
||||
count = countRs.getInt(1);
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(rs, countRs);
|
||||
}
|
||||
return PageResult.success(list, count, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
|
||||
private String getWhereConditionByParam(GlobalLockParam param, List<Object> sqlParamList) {
|
||||
StringBuilder whereConditionBuilder = new StringBuilder();
|
||||
if (StringUtils.isNotBlank(param.getXid())) {
|
||||
whereConditionBuilder.append(" and xid = ? ");
|
||||
sqlParamList.add(param.getXid());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTableName())) {
|
||||
whereConditionBuilder.append(" and table_name = ? ");
|
||||
sqlParamList.add(param.getTableName());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTransactionId())) {
|
||||
whereConditionBuilder.append(" and transaction_id = ? ");
|
||||
sqlParamList.add(param.getTransactionId());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getBranchId())) {
|
||||
whereConditionBuilder.append(" and branch_id = ? ");
|
||||
sqlParamList.add(param.getBranchId());
|
||||
}
|
||||
if (param.getTimeStart() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create >= ? ");
|
||||
sqlParamList.add(param.getTimeStart());
|
||||
}
|
||||
if (param.getTimeEnd() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create <= ? ");
|
||||
sqlParamList.add(param.getTimeEnd());
|
||||
}
|
||||
String whereCondition = whereConditionBuilder.toString();
|
||||
return whereCondition.replaceFirst("and", "where");
|
||||
}
|
||||
private String getWhereConditionByParam(GlobalLockParam param, List<Object> sqlParamList) {
|
||||
StringBuilder whereConditionBuilder = new StringBuilder();
|
||||
if (StringUtils.isNotBlank(param.getXid())) {
|
||||
whereConditionBuilder.append(" and xid = ? ");
|
||||
sqlParamList.add(param.getXid());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTableName())) {
|
||||
whereConditionBuilder.append(" and table_name = ? ");
|
||||
sqlParamList.add(param.getTableName());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTransactionId())) {
|
||||
whereConditionBuilder.append(" and transaction_id = ? ");
|
||||
sqlParamList.add(param.getTransactionId());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getBranchId())) {
|
||||
whereConditionBuilder.append(" and branch_id = ? ");
|
||||
sqlParamList.add(param.getBranchId());
|
||||
}
|
||||
if (param.getTimeStart() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create >= ? ");
|
||||
sqlParamList.add(param.getTimeStart());
|
||||
}
|
||||
if (param.getTimeEnd() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create <= ? ");
|
||||
sqlParamList.add(param.getTimeEnd());
|
||||
}
|
||||
String whereCondition = whereConditionBuilder.toString();
|
||||
return whereCondition.replaceFirst("and", "where");
|
||||
}
|
||||
|
||||
}
|
||||
+88
-86
@@ -58,103 +58,105 @@ import static io.seata.common.DefaultValues.DEFAULT_STORE_DB_GLOBAL_TABLE;
|
||||
@ConditionalOnExpression("#{'db'.equals('${sessionMode}')}")
|
||||
public class GlobalSessionDBServiceImpl implements GlobalSessionService {
|
||||
|
||||
private String globalTable;
|
||||
private String globalTable;
|
||||
|
||||
private String dbType;
|
||||
private String dbType;
|
||||
|
||||
private DataSource dataSource;
|
||||
private DataSource dataSource;
|
||||
|
||||
@Resource(type = BranchSessionService.class)
|
||||
private BranchSessionService branchSessionService;
|
||||
@Resource(type = BranchSessionService.class)
|
||||
private BranchSessionService branchSessionService;
|
||||
|
||||
public GlobalSessionDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
globalTable = configuration.getConfig(ConfigurationKeys.STORE_DB_GLOBAL_TABLE, DEFAULT_STORE_DB_GLOBAL_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
public GlobalSessionDBServiceImpl() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
globalTable = configuration.getConfig(ConfigurationKeys.STORE_DB_GLOBAL_TABLE, DEFAULT_STORE_DB_GLOBAL_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_TYPE + " should not be blank");
|
||||
}
|
||||
String dbDataSource = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
if (StringUtils.isBlank(dbDataSource)) {
|
||||
throw new IllegalArgumentException(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE + " should not be blank");
|
||||
}
|
||||
dataSource = EnhancedServiceLoader.load(DataSourceProvider.class, dbDataSource).provide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
PageUtil.checkParam(param.getPageNum(), param.getPageSize());
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
PageUtil.checkParam(param.getPageNum(), param.getPageSize());
|
||||
|
||||
List<Object> sqlParamList = new ArrayList<>();
|
||||
String whereCondition = getWhereConditionByParam(param, sqlParamList);
|
||||
List<Object> sqlParamList = new ArrayList<>();
|
||||
String whereCondition = getWhereConditionByParam(param, sqlParamList);
|
||||
|
||||
String sourceSql = LogStoreSqlsFactory.getLogStoreSqls(dbType).getAllGlobalSessionSql(globalTable, whereCondition);
|
||||
String querySessionSql = PageUtil.pageSql(sourceSql, dbType, param.getPageNum(), param.getPageSize());
|
||||
String sessionCountSql = PageUtil.countSql(sourceSql, dbType);
|
||||
String sourceSql = LogStoreSqlsFactory.getLogStoreSqls(dbType).getAllGlobalSessionSql(globalTable,
|
||||
whereCondition);
|
||||
String querySessionSql = PageUtil.pageSql(sourceSql, dbType, param.getPageNum(), param.getPageSize());
|
||||
String sessionCountSql = PageUtil.countSql(sourceSql, dbType);
|
||||
|
||||
List<GlobalSessionVO> list = new ArrayList<>();
|
||||
int count = 0;
|
||||
List<GlobalSessionVO> list = new ArrayList<>();
|
||||
int count = 0;
|
||||
|
||||
ResultSet rs = null;
|
||||
ResultSet countRs = null;
|
||||
|
||||
ResultSet rs = null;
|
||||
ResultSet countRs = null;
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(querySessionSql);
|
||||
PreparedStatement countPs = conn.prepareStatement(sessionCountSql)) {
|
||||
PageUtil.setObject(ps, sqlParamList);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(GlobalSessionVO.convert(rs));
|
||||
}
|
||||
|
||||
try (Connection conn = dataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(querySessionSql);
|
||||
PreparedStatement countPs = conn.prepareStatement(sessionCountSql)) {
|
||||
PageUtil.setObject(ps, sqlParamList);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
list.add(GlobalSessionVO.convert(rs));
|
||||
}
|
||||
PageUtil.setObject(countPs, sqlParamList);
|
||||
countRs = countPs.executeQuery();
|
||||
if (countRs.next()) {
|
||||
count = countRs.getInt(1);
|
||||
}
|
||||
if (param.isWithBranch()) {
|
||||
for (GlobalSessionVO globalSessionVO : list) {
|
||||
PageResult<BranchSessionVO> pageResp = branchSessionService.queryByXid(globalSessionVO.getXid());
|
||||
globalSessionVO.setBranchSessionVOs(new HashSet<>(pageResp.getData()));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(rs, countRs);
|
||||
}
|
||||
return PageResult.success(list, count, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
|
||||
PageUtil.setObject(countPs, sqlParamList);
|
||||
countRs = countPs.executeQuery();
|
||||
if (countRs.next()) {
|
||||
count = countRs.getInt(1);
|
||||
}
|
||||
if (param.isWithBranch()) {
|
||||
for (GlobalSessionVO globalSessionVO : list) {
|
||||
PageResult<BranchSessionVO> pageResp = branchSessionService.queryByXid(globalSessionVO.getXid());
|
||||
globalSessionVO.setBranchSessionVOs(new HashSet<>(pageResp.getData()));
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
} finally {
|
||||
IOUtil.close(rs, countRs);
|
||||
}
|
||||
return PageResult.success(list, count, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
|
||||
private String getWhereConditionByParam(GlobalSessionParam param, List<Object> sqlParamList) {
|
||||
StringBuilder whereConditionBuilder = new StringBuilder();
|
||||
if (StringUtils.isNotBlank(param.getXid())) {
|
||||
whereConditionBuilder.append(" and xid = ? ");
|
||||
sqlParamList.add(param.getXid());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getApplicationId())) {
|
||||
whereConditionBuilder.append(" and application_id = ? ");
|
||||
sqlParamList.add(param.getApplicationId());
|
||||
}
|
||||
if (param.getStatus() != null) {
|
||||
whereConditionBuilder.append(" and status = ? ");
|
||||
sqlParamList.add(param.getStatus());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTransactionName())) {
|
||||
whereConditionBuilder.append(" and transaction_name = ? ");
|
||||
sqlParamList.add(param.getTransactionName());
|
||||
}
|
||||
if (param.getTimeStart() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create >= ? ");
|
||||
sqlParamList.add(new Date(param.getTimeStart()));
|
||||
}
|
||||
if (param.getTimeEnd() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create <= ? ");
|
||||
sqlParamList.add(new Date(param.getTimeEnd()));
|
||||
}
|
||||
String whereCondition = whereConditionBuilder.toString();
|
||||
return whereCondition.replaceFirst("and", "where");
|
||||
}
|
||||
private String getWhereConditionByParam(GlobalSessionParam param, List<Object> sqlParamList) {
|
||||
StringBuilder whereConditionBuilder = new StringBuilder();
|
||||
if (StringUtils.isNotBlank(param.getXid())) {
|
||||
whereConditionBuilder.append(" and xid = ? ");
|
||||
sqlParamList.add(param.getXid());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getApplicationId())) {
|
||||
whereConditionBuilder.append(" and application_id = ? ");
|
||||
sqlParamList.add(param.getApplicationId());
|
||||
}
|
||||
if (param.getStatus() != null) {
|
||||
whereConditionBuilder.append(" and status = ? ");
|
||||
sqlParamList.add(param.getStatus());
|
||||
}
|
||||
if (StringUtils.isNotBlank(param.getTransactionName())) {
|
||||
whereConditionBuilder.append(" and transaction_name = ? ");
|
||||
sqlParamList.add(param.getTransactionName());
|
||||
}
|
||||
if (param.getTimeStart() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create >= ? ");
|
||||
sqlParamList.add(new Date(param.getTimeStart()));
|
||||
}
|
||||
if (param.getTimeEnd() != null) {
|
||||
whereConditionBuilder.append(" and gmt_create <= ? ");
|
||||
sqlParamList.add(new Date(param.getTimeEnd()));
|
||||
}
|
||||
String whereCondition = whereConditionBuilder.toString();
|
||||
return whereCondition.replaceFirst("and", "where");
|
||||
}
|
||||
|
||||
}
|
||||
+5
-4
@@ -32,8 +32,9 @@ import org.springframework.stereotype.Component;
|
||||
@ConditionalOnExpression("#{'file'.equals('${sessionMode}')}")
|
||||
public class BranchSessionFileServiceImpl implements BranchSessionService {
|
||||
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
throw new NotSupportYetException();
|
||||
}
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
throw new NotSupportYetException();
|
||||
}
|
||||
|
||||
}
|
||||
+85
-96
@@ -51,120 +51,109 @@ import static java.util.Objects.isNull;
|
||||
@ConditionalOnExpression("#{'file'.equals('${lockMode}')}")
|
||||
public class GlobalLockFileServiceImpl implements GlobalLockService {
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
checkParam(param);
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
checkParam(param);
|
||||
|
||||
final Collection<GlobalSession> allSessions = SessionHolder.getRootSessionManager().allSessions();
|
||||
final Collection<GlobalSession> allSessions = SessionHolder.getRootSessionManager().allSessions();
|
||||
|
||||
final AtomicInteger total = new AtomicInteger();
|
||||
List<RowLock> result = allSessions
|
||||
.parallelStream()
|
||||
.filter(obtainGlobalSessionPredicate(param))
|
||||
.flatMap(globalSession -> globalSession.getBranchSessions().stream())
|
||||
.filter(obtainBranchSessionPredicate(param))
|
||||
.flatMap(branchSession -> filterAndMap(param, branchSession))
|
||||
.peek(globalSession -> total.incrementAndGet())
|
||||
.collect(Collectors.toList());
|
||||
final AtomicInteger total = new AtomicInteger();
|
||||
List<RowLock> result = allSessions.parallelStream().filter(obtainGlobalSessionPredicate(param))
|
||||
.flatMap(globalSession -> globalSession.getBranchSessions().stream())
|
||||
.filter(obtainBranchSessionPredicate(param))
|
||||
.flatMap(branchSession -> filterAndMap(param, branchSession))
|
||||
.peek(globalSession -> total.incrementAndGet()).collect(Collectors.toList());
|
||||
|
||||
return PageResult.build(convert(result), param.getPageNum(), param.getPageSize());
|
||||
return PageResult.build(convert(result), param.getPageNum(), param.getPageSize());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* filter with tableName and generate RowLock
|
||||
*
|
||||
* @param param the query param
|
||||
* @param branchSession the branch session
|
||||
* @return the RowLock list
|
||||
*/
|
||||
private Stream<RowLock> filterAndMap(GlobalLockParam param, BranchSession branchSession) {
|
||||
/**
|
||||
* filter with tableName and generate RowLock
|
||||
* @param param the query param
|
||||
* @param branchSession the branch session
|
||||
* @return the RowLock list
|
||||
*/
|
||||
private Stream<RowLock> filterAndMap(GlobalLockParam param, BranchSession branchSession) {
|
||||
|
||||
final String tableName = param.getTableName();
|
||||
final String tableName = param.getTableName();
|
||||
|
||||
// get rowLock from branchSession
|
||||
final List<RowLock> rowLocks = LockerManagerFactory.getLockManager().collectRowLocks(branchSession);
|
||||
// get rowLock from branchSession
|
||||
final List<RowLock> rowLocks = LockerManagerFactory.getLockManager().collectRowLocks(branchSession);
|
||||
|
||||
if (StringUtils.isNotBlank(tableName)) {
|
||||
return rowLocks.parallelStream().filter(rowLock -> rowLock.getTableName().contains(param.getTableName()));
|
||||
}
|
||||
if (StringUtils.isNotBlank(tableName)) {
|
||||
return rowLocks.parallelStream().filter(rowLock -> rowLock.getTableName().contains(param.getTableName()));
|
||||
}
|
||||
|
||||
return rowLocks.stream();
|
||||
}
|
||||
return rowLocks.stream();
|
||||
}
|
||||
|
||||
/**
|
||||
* check the param
|
||||
* @param param the param
|
||||
*/
|
||||
private void checkParam(GlobalLockParam param) {
|
||||
if (param.getPageSize() <= 0 || param.getPageNum() <= 0) {
|
||||
throw new IllegalArgumentException("wrong pageSize or pageNum");
|
||||
}
|
||||
|
||||
/**
|
||||
* check the param
|
||||
*
|
||||
* @param param the param
|
||||
*/
|
||||
private void checkParam(GlobalLockParam param) {
|
||||
if (param.getPageSize() <= 0 || param.getPageNum() <= 0) {
|
||||
throw new IllegalArgumentException("wrong pageSize or pageNum");
|
||||
}
|
||||
// verification data type
|
||||
try {
|
||||
Long.parseLong(param.getTransactionId());
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
param.setTransactionId(null);
|
||||
}
|
||||
try {
|
||||
Long.parseLong(param.getBranchId());
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
param.setBranchId(null);
|
||||
}
|
||||
|
||||
// verification data type
|
||||
try {
|
||||
Long.parseLong(param.getTransactionId());
|
||||
} catch (NumberFormatException e) {
|
||||
param.setTransactionId(null);
|
||||
}
|
||||
try {
|
||||
Long.parseLong(param.getBranchId());
|
||||
} catch (NumberFormatException e) {
|
||||
param.setBranchId(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the branch session condition
|
||||
* @param param condition for query branch session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super BranchSession> obtainBranchSessionPredicate(GlobalLockParam param) {
|
||||
return branchSession -> {
|
||||
// transactionId
|
||||
return (isBlank(param.getTransactionId())
|
||||
|| String.valueOf(branchSession.getTransactionId()).contains(param.getTransactionId()))
|
||||
|
||||
}
|
||||
&&
|
||||
// branch id
|
||||
(isBlank(param.getBranchId()) || String.valueOf(branchSession.getBranchId()).contains(param.getBranchId()));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the branch session condition
|
||||
*
|
||||
* @param param condition for query branch session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super BranchSession> obtainBranchSessionPredicate(GlobalLockParam param) {
|
||||
return branchSession -> {
|
||||
// transactionId
|
||||
return (isBlank(param.getTransactionId()) ||
|
||||
String.valueOf(branchSession.getTransactionId()).contains(param.getTransactionId()))
|
||||
/**
|
||||
* obtain the global session condition
|
||||
* @param param condition for query global session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super GlobalSession> obtainGlobalSessionPredicate(GlobalLockParam param) {
|
||||
|
||||
&&
|
||||
// branch id
|
||||
(isBlank(param.getBranchId()) ||
|
||||
String.valueOf(branchSession.getBranchId()).contains(param.getBranchId()))
|
||||
;
|
||||
};
|
||||
}
|
||||
return globalSession -> {
|
||||
// first, there must be withBranchSession
|
||||
return CollectionUtils.isNotEmpty(globalSession.getBranchSessions())
|
||||
|
||||
&&
|
||||
// The second is other conditions
|
||||
// xid
|
||||
(isBlank(param.getXid()) || globalSession.getXid().contains(param.getXid()))
|
||||
|
||||
/**
|
||||
* obtain the global session condition
|
||||
*
|
||||
* @param param condition for query global session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super GlobalSession> obtainGlobalSessionPredicate(GlobalLockParam param) {
|
||||
|
||||
return globalSession -> {
|
||||
// first, there must be withBranchSession
|
||||
return CollectionUtils.isNotEmpty(globalSession.getBranchSessions())
|
||||
|
||||
&&
|
||||
// The second is other conditions
|
||||
// xid
|
||||
(isBlank(param.getXid()) || globalSession.getXid().contains(param.getXid()))
|
||||
|
||||
&&
|
||||
// timeStart
|
||||
(isNull(param.getTimeStart()) || param.getTimeStart() <= globalSession.getBeginTime())
|
||||
|
||||
&&
|
||||
// timeEnd
|
||||
(isNull(param.getTimeEnd()) || param.getTimeEnd() >= globalSession.getBeginTime());
|
||||
};
|
||||
}
|
||||
&&
|
||||
// timeStart
|
||||
(isNull(param.getTimeStart()) || param.getTimeStart() <= globalSession.getBeginTime())
|
||||
|
||||
&&
|
||||
// timeEnd
|
||||
(isNull(param.getTimeEnd()) || param.getTimeEnd() >= globalSession.getBeginTime());
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+38
-42
@@ -45,58 +45,54 @@ import static java.util.Objects.isNull;
|
||||
@ConditionalOnExpression("#{'file'.equals('${sessionMode}')}")
|
||||
public class GlobalSessionFileServiceImpl implements GlobalSessionService {
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
if (param.getPageSize() <= 0 || param.getPageNum() <= 0) {
|
||||
throw new IllegalArgumentException("wrong pageSize or pageNum");
|
||||
}
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
if (param.getPageSize() <= 0 || param.getPageNum() <= 0) {
|
||||
throw new IllegalArgumentException("wrong pageSize or pageNum");
|
||||
}
|
||||
|
||||
final Collection<GlobalSession> allSessions = SessionHolder.getRootSessionManager().allSessions();
|
||||
final Collection<GlobalSession> allSessions = SessionHolder.getRootSessionManager().allSessions();
|
||||
|
||||
final List<GlobalSession> filteredSessions = allSessions
|
||||
.parallelStream()
|
||||
.filter(obtainPredicate(param))
|
||||
.collect(Collectors.toList());
|
||||
final List<GlobalSession> filteredSessions = allSessions.parallelStream().filter(obtainPredicate(param))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return PageResult.build(SessionConverter.convertGlobalSession(filteredSessions), param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
return PageResult.build(SessionConverter.convertGlobalSession(filteredSessions), param.getPageNum(),
|
||||
param.getPageSize());
|
||||
}
|
||||
|
||||
/**
|
||||
* obtain the condition
|
||||
* @param param condition for query global session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super GlobalSession> obtainPredicate(GlobalSessionParam param) {
|
||||
|
||||
return session -> {
|
||||
return
|
||||
// xid
|
||||
(isBlank(param.getXid()) || session.getXid().contains(param.getXid()))
|
||||
|
||||
/**
|
||||
* obtain the condition
|
||||
*
|
||||
* @param param condition for query global session
|
||||
* @return the filter condition
|
||||
*/
|
||||
private Predicate<? super GlobalSession> obtainPredicate(GlobalSessionParam param) {
|
||||
&&
|
||||
// applicationId
|
||||
(isBlank(param.getApplicationId()) || session.getApplicationId().contains(param.getApplicationId()))
|
||||
|
||||
return session -> {
|
||||
return
|
||||
// xid
|
||||
(isBlank(param.getXid()) || session.getXid().contains(param.getXid()))
|
||||
&&
|
||||
// status
|
||||
(isNull(param.getStatus()) || Objects.equals(session.getStatus().getCode(), param.getStatus()))
|
||||
|
||||
&&
|
||||
// applicationId
|
||||
(isBlank(param.getApplicationId()) || session.getApplicationId().contains(param.getApplicationId()))
|
||||
&&
|
||||
// transactionName
|
||||
(isBlank(param.getTransactionName()) || session.getTransactionName().contains(param.getTransactionName()))
|
||||
|
||||
&&
|
||||
// status
|
||||
(isNull(param.getStatus()) || Objects.equals(session.getStatus().getCode(), param.getStatus()))
|
||||
&&
|
||||
// timeStart
|
||||
(isNull(param.getTimeStart()) || param.getTimeStart() <= session.getBeginTime())
|
||||
|
||||
&&
|
||||
// transactionName
|
||||
(isBlank(param.getTransactionName()) || session.getTransactionName().contains(param.getTransactionName()))
|
||||
&&
|
||||
// timeEnd
|
||||
(isNull(param.getTimeEnd()) || param.getTimeEnd() >= session.getBeginTime());
|
||||
|
||||
&&
|
||||
// timeStart
|
||||
(isNull(param.getTimeStart()) || param.getTimeStart() <= session.getBeginTime())
|
||||
|
||||
&&
|
||||
// timeEnd
|
||||
(isNull(param.getTimeEnd()) || param.getTimeEnd() >= session.getBeginTime());
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+18
-17
@@ -40,26 +40,27 @@ import java.util.List;
|
||||
@ConditionalOnExpression("#{'redis'.equals('${sessionMode}')}")
|
||||
public class BranchSessionRedisServiceImpl implements BranchSessionService {
|
||||
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
if (StringUtils.isBlank(xid)) {
|
||||
return PageResult.success();
|
||||
}
|
||||
@Override
|
||||
public PageResult<BranchSessionVO> queryByXid(String xid) {
|
||||
if (StringUtils.isBlank(xid)) {
|
||||
return PageResult.success();
|
||||
}
|
||||
|
||||
List<BranchSessionVO> branchSessionVos = new ArrayList<>();
|
||||
List<BranchSessionVO> branchSessionVos = new ArrayList<>();
|
||||
|
||||
RedisTransactionStoreManager instance = RedisTransactionStoreManager.getInstance();
|
||||
RedisTransactionStoreManager instance = RedisTransactionStoreManager.getInstance();
|
||||
|
||||
List<BranchTransactionDO> branchSessionDos = instance.findBranchSessionByXid(xid);
|
||||
List<BranchTransactionDO> branchSessionDos = instance.findBranchSessionByXid(xid);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(branchSessionDos)) {
|
||||
for (BranchTransactionDO branchSessionDo : branchSessionDos) {
|
||||
BranchSessionVO branchSessionVO = new BranchSessionVO();
|
||||
BeanUtils.copyProperties(branchSessionDo, branchSessionVO);
|
||||
branchSessionVos.add(branchSessionVO);
|
||||
}
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(branchSessionDos)) {
|
||||
for (BranchTransactionDO branchSessionDo : branchSessionDos) {
|
||||
BranchSessionVO branchSessionVO = new BranchSessionVO();
|
||||
BeanUtils.copyProperties(branchSessionDo, branchSessionVO);
|
||||
branchSessionVos.add(branchSessionVO);
|
||||
}
|
||||
}
|
||||
|
||||
return PageResult.success(branchSessionVos, branchSessionVos.size(), 0, branchSessionVos.size());
|
||||
}
|
||||
|
||||
return PageResult.success(branchSessionVos, branchSessionVos.size(), 0, branchSessionVos.size());
|
||||
}
|
||||
}
|
||||
+63
-61
@@ -39,6 +39,7 @@ import static io.seata.core.constants.RedisKeyConstants.*;
|
||||
|
||||
/**
|
||||
* Global Lock Redis Service Impl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author doubleDimple
|
||||
*/
|
||||
@@ -47,73 +48,74 @@ import static io.seata.core.constants.RedisKeyConstants.*;
|
||||
@ConditionalOnExpression("#{'redis'.equals('${lockMode}')}")
|
||||
public class GlobalLockRedisServiceImpl implements GlobalLockService {
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
@Override
|
||||
public PageResult<GlobalLockVO> query(GlobalLockParam param) {
|
||||
|
||||
int total = 0;
|
||||
List<GlobalLockVO> globalLockVos;
|
||||
checkPage(param);
|
||||
if (isNotBlank(param.getXid())) {
|
||||
globalLockVos = queryGlobalByXid(param.getXid());
|
||||
total = globalLockVos.size();
|
||||
return PageResult.success(globalLockVos,total,param.getPageNum(),param.getPageSize());
|
||||
} else if (isNotBlank(param.getTableName()) && isNotBlank(param.getPk()) && isNotBlank(param.getResourceId())) {
|
||||
//SEATA_ROW_LOCK_jdbc:mysql://116.62.62.26/seata-order^^^order^^^2188
|
||||
String tableName = param.getTableName();
|
||||
String pk = param.getPk();
|
||||
String resourceId = param.getResourceId();
|
||||
globalLockVos = queryGlobalLockByRowKey(buildRowKey(tableName,pk,resourceId));
|
||||
total = globalLockVos.size();
|
||||
return PageResult.success(globalLockVos,total,param.getPageNum(),param.getPageSize());
|
||||
} else {
|
||||
return PageResult.failure(ParameterRequired.getErrCode(),"only three parameters of tableName,pk,resourceId or Xid are supported");
|
||||
}
|
||||
}
|
||||
int total = 0;
|
||||
List<GlobalLockVO> globalLockVos;
|
||||
checkPage(param);
|
||||
if (isNotBlank(param.getXid())) {
|
||||
globalLockVos = queryGlobalByXid(param.getXid());
|
||||
total = globalLockVos.size();
|
||||
return PageResult.success(globalLockVos, total, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
else if (isNotBlank(param.getTableName()) && isNotBlank(param.getPk()) && isNotBlank(param.getResourceId())) {
|
||||
// SEATA_ROW_LOCK_jdbc:mysql://116.62.62.26/seata-order^^^order^^^2188
|
||||
String tableName = param.getTableName();
|
||||
String pk = param.getPk();
|
||||
String resourceId = param.getResourceId();
|
||||
globalLockVos = queryGlobalLockByRowKey(buildRowKey(tableName, pk, resourceId));
|
||||
total = globalLockVos.size();
|
||||
return PageResult.success(globalLockVos, total, param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
else {
|
||||
return PageResult.failure(ParameterRequired.getErrCode(),
|
||||
"only three parameters of tableName,pk,resourceId or Xid are supported");
|
||||
}
|
||||
}
|
||||
|
||||
private List<GlobalLockVO> queryGlobalLockByRowKey(String buildRowKey) {
|
||||
return readGlobalLockByRowKey(buildRowKey);
|
||||
}
|
||||
private List<GlobalLockVO> queryGlobalLockByRowKey(String buildRowKey) {
|
||||
return readGlobalLockByRowKey(buildRowKey);
|
||||
}
|
||||
|
||||
private String buildRowKey(String tableName, String pk,String resourceId) {
|
||||
return DEFAULT_REDIS_SEATA_ROW_LOCK_PREFIX + resourceId + SPLIT + tableName + SPLIT + pk;
|
||||
}
|
||||
private String buildRowKey(String tableName, String pk, String resourceId) {
|
||||
return DEFAULT_REDIS_SEATA_ROW_LOCK_PREFIX + resourceId + SPLIT + tableName + SPLIT + pk;
|
||||
}
|
||||
|
||||
private List<GlobalLockVO> queryGlobalByXid(String xid) {
|
||||
return readGlobalLockByXid(DEFAULT_REDIS_SEATA_GLOBAL_LOCK_PREFIX + xid);
|
||||
}
|
||||
|
||||
private List<GlobalLockVO> queryGlobalByXid(String xid) {
|
||||
return readGlobalLockByXid(DEFAULT_REDIS_SEATA_GLOBAL_LOCK_PREFIX + xid);
|
||||
}
|
||||
private List<GlobalLockVO> readGlobalLockByXid(String key) {
|
||||
List<GlobalLockVO> vos = new ArrayList<>();
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
Map<String, String> mapGlobalKeys = jedis.hgetAll(key);
|
||||
if (CollectionUtils.isNotEmpty(mapGlobalKeys)) {
|
||||
List<String> rowLockKeys = new ArrayList<>();
|
||||
mapGlobalKeys.forEach((k, v) -> rowLockKeys.addAll(Arrays.asList(v.split(ROW_LOCK_KEY_SPLIT_CHAR))));
|
||||
for (String rowLoclKey : rowLockKeys) {
|
||||
Map<String, String> mapRowLockKey = jedis.hgetAll(rowLoclKey);
|
||||
GlobalLockVO vo = (GlobalLockVO) BeanUtils.mapToObject(mapRowLockKey, GlobalLockVO.class);
|
||||
if (vo != null) {
|
||||
vos.add(vo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<GlobalLockVO> readGlobalLockByXid(String key) {
|
||||
List<GlobalLockVO> vos = new ArrayList<>();
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
Map<String, String> mapGlobalKeys = jedis.hgetAll(key);
|
||||
if (CollectionUtils.isNotEmpty(mapGlobalKeys)) {
|
||||
List<String> rowLockKeys = new ArrayList<>();
|
||||
mapGlobalKeys.forEach((k,v) -> rowLockKeys.addAll(Arrays.asList(v.split(ROW_LOCK_KEY_SPLIT_CHAR))));
|
||||
for (String rowLoclKey : rowLockKeys) {
|
||||
Map<String, String> mapRowLockKey = jedis.hgetAll(rowLoclKey);
|
||||
GlobalLockVO vo = (GlobalLockVO)BeanUtils.mapToObject(mapRowLockKey, GlobalLockVO.class);
|
||||
if (vo != null) {
|
||||
vos.add(vo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return vos;
|
||||
}
|
||||
|
||||
return vos;
|
||||
}
|
||||
|
||||
|
||||
private List<GlobalLockVO> readGlobalLockByRowKey(String key) {
|
||||
List<GlobalLockVO> vos = new ArrayList<>();
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
Map<String, String> map = jedis.hgetAll(key);
|
||||
GlobalLockVO vo = (GlobalLockVO)BeanUtils.mapToObject(map, GlobalLockVO.class);
|
||||
if (vo != null) {
|
||||
vos.add(vo);
|
||||
}
|
||||
}
|
||||
return vos;
|
||||
}
|
||||
private List<GlobalLockVO> readGlobalLockByRowKey(String key) {
|
||||
List<GlobalLockVO> vos = new ArrayList<>();
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
Map<String, String> map = jedis.hgetAll(key);
|
||||
GlobalLockVO vo = (GlobalLockVO) BeanUtils.mapToObject(map, GlobalLockVO.class);
|
||||
if (vo != null) {
|
||||
vos.add(vo);
|
||||
}
|
||||
}
|
||||
return vos;
|
||||
}
|
||||
|
||||
}
|
||||
+55
-49
@@ -41,6 +41,7 @@ import static io.seata.server.storage.SessionConverter.convertToGlobalSessionVo;
|
||||
|
||||
/**
|
||||
* Global Session Redis ServiceImpl
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author doubleDimple
|
||||
*/
|
||||
@@ -49,62 +50,67 @@ import static io.seata.server.storage.SessionConverter.convertToGlobalSessionVo;
|
||||
@ConditionalOnExpression("#{'redis'.equals('${sessionMode}')}")
|
||||
public class GlobalSessionRedisServiceImpl implements GlobalSessionService {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalSessionRedisServiceImpl.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(GlobalSessionRedisServiceImpl.class);
|
||||
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
List<GlobalSessionVO> result = new ArrayList<>();
|
||||
Long total = 0L;
|
||||
if (param.getTimeStart() != null || param.getTimeEnd() != null) {
|
||||
//not support time range query
|
||||
LOGGER.debug("not supported according to time range query");
|
||||
return PageResult.failure(ParameterRequired.getErrCode(),"not supported according to time range query");
|
||||
}
|
||||
List<GlobalSession> globalSessions = new ArrayList<>();
|
||||
@Override
|
||||
public PageResult<GlobalSessionVO> query(GlobalSessionParam param) {
|
||||
List<GlobalSessionVO> result = new ArrayList<>();
|
||||
Long total = 0L;
|
||||
if (param.getTimeStart() != null || param.getTimeEnd() != null) {
|
||||
// not support time range query
|
||||
LOGGER.debug("not supported according to time range query");
|
||||
return PageResult.failure(ParameterRequired.getErrCode(), "not supported according to time range query");
|
||||
}
|
||||
List<GlobalSession> globalSessions = new ArrayList<>();
|
||||
|
||||
RedisTransactionStoreManager instance = RedisTransactionStoreManager.getInstance();
|
||||
RedisTransactionStoreManager instance = RedisTransactionStoreManager.getInstance();
|
||||
|
||||
checkPage(param);
|
||||
checkPage(param);
|
||||
|
||||
if (isBlank(param.getXid()) && param.getStatus() == null) {
|
||||
total = instance.countByGlobalSessions(GlobalStatus.values());
|
||||
globalSessions = instance.findGlobalSessionByPage(param.getPageNum(), param.getPageSize(),param.isWithBranch());
|
||||
} else {
|
||||
List<GlobalSession> globalSessionsNew = new ArrayList<>();
|
||||
if (isNotBlank(param.getXid())) {
|
||||
SessionCondition sessionCondition = new SessionCondition();
|
||||
sessionCondition.setXid(param.getXid());
|
||||
sessionCondition.setLazyLoadBranch(!param.isWithBranch());
|
||||
globalSessions = instance.readSession(sessionCondition);
|
||||
total = (long)globalSessions.size();
|
||||
}
|
||||
if (isBlank(param.getXid()) && param.getStatus() == null) {
|
||||
total = instance.countByGlobalSessions(GlobalStatus.values());
|
||||
globalSessions = instance.findGlobalSessionByPage(param.getPageNum(), param.getPageSize(),
|
||||
param.isWithBranch());
|
||||
}
|
||||
else {
|
||||
List<GlobalSession> globalSessionsNew = new ArrayList<>();
|
||||
if (isNotBlank(param.getXid())) {
|
||||
SessionCondition sessionCondition = new SessionCondition();
|
||||
sessionCondition.setXid(param.getXid());
|
||||
sessionCondition.setLazyLoadBranch(!param.isWithBranch());
|
||||
globalSessions = instance.readSession(sessionCondition);
|
||||
total = (long) globalSessions.size();
|
||||
}
|
||||
|
||||
if (param.getStatus() != null && GlobalStatus.get(param.getStatus()) != null) {
|
||||
if (CollectionUtils.isNotEmpty(globalSessions)) {
|
||||
globalSessionsNew = globalSessions.stream().filter(globalSession -> globalSession.getStatus().getCode() == (param.getStatus())).collect(Collectors.toList());
|
||||
total = (long)globalSessionsNew.size();
|
||||
} else {
|
||||
total = instance.countByGlobalSessions(new GlobalStatus[] {GlobalStatus.get(param.getStatus())});
|
||||
globalSessionsNew = instance.readSessionStatusByPage(param);
|
||||
}
|
||||
}
|
||||
if (param.getStatus() != null && GlobalStatus.get(param.getStatus()) != null) {
|
||||
if (CollectionUtils.isNotEmpty(globalSessions)) {
|
||||
globalSessionsNew = globalSessions.stream()
|
||||
.filter(globalSession -> globalSession.getStatus().getCode() == (param.getStatus()))
|
||||
.collect(Collectors.toList());
|
||||
total = (long) globalSessionsNew.size();
|
||||
}
|
||||
else {
|
||||
total = instance.countByGlobalSessions(new GlobalStatus[] { GlobalStatus.get(param.getStatus()) });
|
||||
globalSessionsNew = instance.readSessionStatusByPage(param);
|
||||
}
|
||||
}
|
||||
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
if (isNotBlank(param.getApplicationId())) {
|
||||
//not support
|
||||
LOGGER.debug("not supported according to applicationId query");
|
||||
}
|
||||
if (isNotBlank(param.getTransactionName())) {
|
||||
//not support
|
||||
LOGGER.debug("not supported according to transactionName query");
|
||||
}
|
||||
}
|
||||
globalSessions = globalSessionsNew.size() > 0 ? globalSessionsNew : globalSessions;
|
||||
}
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
if (isNotBlank(param.getApplicationId())) {
|
||||
// not support
|
||||
LOGGER.debug("not supported according to applicationId query");
|
||||
}
|
||||
if (isNotBlank(param.getTransactionName())) {
|
||||
// not support
|
||||
LOGGER.debug("not supported according to transactionName query");
|
||||
}
|
||||
}
|
||||
globalSessions = globalSessionsNew.size() > 0 ? globalSessionsNew : globalSessions;
|
||||
}
|
||||
|
||||
convertToGlobalSessionVo(result,globalSessions);
|
||||
convertToGlobalSessionVo(result, globalSessions);
|
||||
|
||||
return PageResult.success(result,total.intValue(),param.getPageNum(),param.getPageSize());
|
||||
}
|
||||
return PageResult.success(result, total.intValue(), param.getPageNum(), param.getPageSize());
|
||||
}
|
||||
|
||||
}
|
||||
+74
-72
@@ -21,94 +21,96 @@ import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Global lock param
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class GlobalLockParam extends BaseParam implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 615412528070131284L;
|
||||
private static final long serialVersionUID = 615412528070131284L;
|
||||
|
||||
/**
|
||||
* the xid
|
||||
*/
|
||||
private String xid;
|
||||
/**
|
||||
* the table name
|
||||
*/
|
||||
private String tableName;
|
||||
/**
|
||||
* the transaction id
|
||||
*/
|
||||
private String transactionId;
|
||||
/**
|
||||
* the branch id
|
||||
*/
|
||||
private String branchId;
|
||||
/**
|
||||
* the primary Key
|
||||
*/
|
||||
private String pk;
|
||||
/**
|
||||
* the resourceId
|
||||
*/
|
||||
private String resourceId;
|
||||
/**
|
||||
* the xid
|
||||
*/
|
||||
private String xid;
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
/**
|
||||
* the table name
|
||||
*/
|
||||
private String tableName;
|
||||
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
/**
|
||||
* the transaction id
|
||||
*/
|
||||
private String transactionId;
|
||||
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
/**
|
||||
* the branch id
|
||||
*/
|
||||
private String branchId;
|
||||
|
||||
public void setBranchId(String branchId) {
|
||||
this.branchId = branchId;
|
||||
}
|
||||
/**
|
||||
* the primary Key
|
||||
*/
|
||||
private String pk;
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
/**
|
||||
* the resourceId
|
||||
*/
|
||||
private String resourceId;
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
public void setTransactionId(String transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
public String getPk() {
|
||||
return pk;
|
||||
}
|
||||
public void setBranchId(String branchId) {
|
||||
this.branchId = branchId;
|
||||
}
|
||||
|
||||
public void setPk(String pk) {
|
||||
this.pk = pk;
|
||||
}
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getPk() {
|
||||
return pk;
|
||||
}
|
||||
|
||||
public void setPk(String pk) {
|
||||
this.pk = pk;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalLockParam{" + "xid='" + xid + '\'' + ", tableName='" + tableName + '\'' + ", transactionId='"
|
||||
+ transactionId + '\'' + ", branchId='" + branchId + '\'' + ", pk='" + pk + '\'' + ", resourceId='"
|
||||
+ resourceId + '\'' + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalLockParam{" +
|
||||
"xid='" + xid + '\'' +
|
||||
", tableName='" + tableName + '\'' +
|
||||
", transactionId='" + transactionId + '\'' +
|
||||
", branchId='" + branchId + '\'' +
|
||||
", pk='" + pk + '\'' +
|
||||
", resourceId='" + resourceId + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+63
-63
@@ -21,82 +21,82 @@ import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Global session param
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class GlobalSessionParam extends BaseParam implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 115488252809011284L;
|
||||
/**
|
||||
* the xid
|
||||
*/
|
||||
private String xid;
|
||||
/**
|
||||
* the application id
|
||||
*/
|
||||
private String applicationId;
|
||||
/**
|
||||
* the global session status
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* the transaction name
|
||||
*/
|
||||
private String transactionName;
|
||||
/**
|
||||
* if with branch
|
||||
* true: with branch session
|
||||
* false: no branch session
|
||||
*/
|
||||
private boolean withBranch;
|
||||
private static final long serialVersionUID = 115488252809011284L;
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
/**
|
||||
* the xid
|
||||
*/
|
||||
private String xid;
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
/**
|
||||
* the application id
|
||||
*/
|
||||
private String applicationId;
|
||||
|
||||
public String getTransactionName() {
|
||||
return transactionName;
|
||||
}
|
||||
/**
|
||||
* the global session status
|
||||
*/
|
||||
private Integer status;
|
||||
|
||||
public void setTransactionName(String transactionName) {
|
||||
this.transactionName = transactionName;
|
||||
}
|
||||
/**
|
||||
* the transaction name
|
||||
*/
|
||||
private String transactionName;
|
||||
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
/**
|
||||
* if with branch true: with branch session false: no branch session
|
||||
*/
|
||||
private boolean withBranch;
|
||||
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
public String getTransactionName() {
|
||||
return transactionName;
|
||||
}
|
||||
|
||||
public boolean isWithBranch() {
|
||||
return withBranch;
|
||||
}
|
||||
public void setTransactionName(String transactionName) {
|
||||
this.transactionName = transactionName;
|
||||
}
|
||||
|
||||
public void setWithBranch(boolean withBranch) {
|
||||
this.withBranch = withBranch;
|
||||
}
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public boolean isWithBranch() {
|
||||
return withBranch;
|
||||
}
|
||||
|
||||
public void setWithBranch(boolean withBranch) {
|
||||
this.withBranch = withBranch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalSessionParam{" + "xid='" + xid + '\'' + ", applicationId='" + applicationId + '\'' + ", status="
|
||||
+ status + ", transactionName='" + transactionName + '\'' + ", withBranch=" + withBranch + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalSessionParam{" +
|
||||
"xid='" + xid + '\'' +
|
||||
", applicationId='" + applicationId + '\'' +
|
||||
", status=" + status +
|
||||
", transactionName='" + transactionName + '\'' +
|
||||
", withBranch=" + withBranch +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+7
-6
@@ -20,15 +20,16 @@ import io.seata.server.console.vo.BranchSessionVO;
|
||||
|
||||
/**
|
||||
* Branch session service
|
||||
*
|
||||
* @author wangzhongxiang
|
||||
*/
|
||||
public interface BranchSessionService {
|
||||
|
||||
/**
|
||||
* Query branch session by xid
|
||||
* @param xid the xid
|
||||
* @return the BranchSessionVO list
|
||||
*/
|
||||
PageResult<BranchSessionVO> queryByXid(String xid);
|
||||
/**
|
||||
* Query branch session by xid
|
||||
* @param xid the xid
|
||||
* @return the BranchSessionVO list
|
||||
*/
|
||||
PageResult<BranchSessionVO> queryByXid(String xid);
|
||||
|
||||
}
|
||||
+7
-8
@@ -19,19 +19,18 @@ import io.seata.console.result.PageResult;
|
||||
import io.seata.server.console.param.GlobalLockParam;
|
||||
import io.seata.server.console.vo.GlobalLockVO;
|
||||
|
||||
|
||||
/**
|
||||
* Global lock service
|
||||
*
|
||||
* @author wangzhongxiang
|
||||
*/
|
||||
public interface GlobalLockService {
|
||||
|
||||
/**
|
||||
* Query locks by param
|
||||
* @param param the param
|
||||
* @return the list of GlobalLockVO
|
||||
*/
|
||||
PageResult<GlobalLockVO> query(GlobalLockParam param);
|
||||
|
||||
/**
|
||||
* Query locks by param
|
||||
* @param param the param
|
||||
* @return the list of GlobalLockVO
|
||||
*/
|
||||
PageResult<GlobalLockVO> query(GlobalLockParam param);
|
||||
|
||||
}
|
||||
+7
-6
@@ -21,15 +21,16 @@ import io.seata.server.console.vo.GlobalSessionVO;
|
||||
|
||||
/**
|
||||
* Global session service
|
||||
*
|
||||
* @author wangzhongxiang
|
||||
*/
|
||||
public interface GlobalSessionService {
|
||||
|
||||
/**
|
||||
* Query global session
|
||||
* @param param the param
|
||||
* @return the GlobalSessionVO list
|
||||
*/
|
||||
PageResult<GlobalSessionVO> query(GlobalSessionParam param);
|
||||
/**
|
||||
* Query global session
|
||||
* @param param the param
|
||||
* @return the GlobalSessionVO list
|
||||
*/
|
||||
PageResult<GlobalSessionVO> query(GlobalSessionParam param);
|
||||
|
||||
}
|
||||
+142
-170
@@ -24,218 +24,190 @@ import java.util.Objects;
|
||||
|
||||
/**
|
||||
* BranchSessionVO
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class BranchSessionVO {
|
||||
|
||||
private String xid;
|
||||
private String xid;
|
||||
|
||||
private String transactionId;
|
||||
private String transactionId;
|
||||
|
||||
private String branchId;
|
||||
private String branchId;
|
||||
|
||||
private String resourceGroupId;
|
||||
private String resourceGroupId;
|
||||
|
||||
private String resourceId;
|
||||
private String resourceId;
|
||||
|
||||
private String branchType;
|
||||
private String branchType;
|
||||
|
||||
private Integer status;
|
||||
private Integer status;
|
||||
|
||||
private String clientId;
|
||||
private String clientId;
|
||||
|
||||
private String applicationData;
|
||||
private String applicationData;
|
||||
|
||||
private Long gmtCreate;
|
||||
private Long gmtCreate;
|
||||
|
||||
private Long gmtModified;
|
||||
private Long gmtModified;
|
||||
|
||||
public BranchSessionVO() {
|
||||
|
||||
public BranchSessionVO(){
|
||||
}
|
||||
|
||||
}
|
||||
public BranchSessionVO(String xid, Long transactionId, Long branchId, String resourceGroupId, String resourceId,
|
||||
String branchType, Integer status, String clientId, String applicationData) {
|
||||
this.xid = xid;
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
this.branchId = String.valueOf(branchId);
|
||||
this.resourceGroupId = resourceGroupId;
|
||||
this.resourceId = resourceId;
|
||||
this.branchType = branchType;
|
||||
this.status = status;
|
||||
this.clientId = clientId;
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
|
||||
public BranchSessionVO(String xid,
|
||||
Long transactionId,
|
||||
Long branchId,
|
||||
String resourceGroupId,
|
||||
String resourceId,
|
||||
String branchType,
|
||||
Integer status,
|
||||
String clientId,
|
||||
String applicationData) {
|
||||
this.xid = xid;
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
this.branchId = String.valueOf(branchId);
|
||||
this.resourceGroupId = resourceGroupId;
|
||||
this.resourceId = resourceId;
|
||||
this.branchType = branchType;
|
||||
this.status = status;
|
||||
this.clientId = clientId;
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
public void setBranchId(Long branchId) {
|
||||
this.branchId = String.valueOf(branchId);
|
||||
}
|
||||
|
||||
public void setBranchId(Long branchId) {
|
||||
this.branchId = String.valueOf(branchId);
|
||||
}
|
||||
public String getResourceGroupId() {
|
||||
return resourceGroupId;
|
||||
}
|
||||
|
||||
public String getResourceGroupId() {
|
||||
return resourceGroupId;
|
||||
}
|
||||
public void setResourceGroupId(String resourceGroupId) {
|
||||
this.resourceGroupId = resourceGroupId;
|
||||
}
|
||||
|
||||
public void setResourceGroupId(String resourceGroupId) {
|
||||
this.resourceGroupId = resourceGroupId;
|
||||
}
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
public String getBranchType() {
|
||||
return branchType;
|
||||
}
|
||||
|
||||
public String getBranchType() {
|
||||
return branchType;
|
||||
}
|
||||
public void setBranchType(String branchType) {
|
||||
this.branchType = branchType;
|
||||
}
|
||||
|
||||
public void setBranchType(String branchType) {
|
||||
this.branchType = branchType;
|
||||
}
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
public String getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
|
||||
public String getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
public void setApplicationData(String applicationData) {
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
|
||||
public void setApplicationData(String applicationData) {
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
public static BranchSessionVO convert(ResultSet rs) throws SQLException {
|
||||
BranchSessionVO branchSessionVO = new BranchSessionVO();
|
||||
branchSessionVO.setXid(rs.getString(ServerTableColumnsName.BRANCH_TABLE_XID));
|
||||
branchSessionVO.setTransactionId(rs.getLong(ServerTableColumnsName.BRANCH_TABLE_TRANSACTION_ID));
|
||||
branchSessionVO.setBranchId(rs.getLong(ServerTableColumnsName.BRANCH_TABLE_BRANCH_ID));
|
||||
branchSessionVO.setResourceGroupId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_RESOURCE_GROUP_ID));
|
||||
branchSessionVO.setResourceId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_RESOURCE_ID));
|
||||
branchSessionVO.setBranchType(rs.getString(ServerTableColumnsName.BRANCH_TABLE_BRANCH_TYPE));
|
||||
branchSessionVO.setStatus(rs.getInt(ServerTableColumnsName.BRANCH_TABLE_STATUS));
|
||||
branchSessionVO.setClientId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_CLIENT_ID));
|
||||
branchSessionVO.setApplicationData(rs.getString(ServerTableColumnsName.BRANCH_TABLE_APPLICATION_DATA));
|
||||
Date gmtCreateTimestamp = rs.getDate(ServerTableColumnsName.BRANCH_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
branchSessionVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Date gmtModifiedTimestamp = rs.getDate(ServerTableColumnsName.BRANCH_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
branchSessionVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return branchSessionVO;
|
||||
}
|
||||
|
||||
public static BranchSessionVO convert(ResultSet rs) throws SQLException {
|
||||
BranchSessionVO branchSessionVO = new BranchSessionVO();
|
||||
branchSessionVO.setXid(rs.getString(ServerTableColumnsName.BRANCH_TABLE_XID));
|
||||
branchSessionVO.setTransactionId(rs.getLong(ServerTableColumnsName.BRANCH_TABLE_TRANSACTION_ID));
|
||||
branchSessionVO.setBranchId(rs.getLong(ServerTableColumnsName.BRANCH_TABLE_BRANCH_ID));
|
||||
branchSessionVO.setResourceGroupId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_RESOURCE_GROUP_ID));
|
||||
branchSessionVO.setResourceId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_RESOURCE_ID));
|
||||
branchSessionVO.setBranchType(rs.getString(ServerTableColumnsName.BRANCH_TABLE_BRANCH_TYPE));
|
||||
branchSessionVO.setStatus(rs.getInt(ServerTableColumnsName.BRANCH_TABLE_STATUS));
|
||||
branchSessionVO.setClientId(rs.getString(ServerTableColumnsName.BRANCH_TABLE_CLIENT_ID));
|
||||
branchSessionVO.setApplicationData(rs.getString(ServerTableColumnsName.BRANCH_TABLE_APPLICATION_DATA));
|
||||
Date gmtCreateTimestamp = rs.getDate(ServerTableColumnsName.BRANCH_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
branchSessionVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Date gmtModifiedTimestamp = rs.getDate(ServerTableColumnsName.BRANCH_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
branchSessionVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return branchSessionVO;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
BranchSessionVO that = (BranchSessionVO) o;
|
||||
return Objects.equals(xid, that.xid) && Objects.equals(transactionId, that.transactionId)
|
||||
&& Objects.equals(branchId, that.branchId) && Objects.equals(resourceGroupId, that.resourceGroupId)
|
||||
&& Objects.equals(resourceId, that.resourceId) && Objects.equals(branchType, that.branchType)
|
||||
&& Objects.equals(status, that.status) && Objects.equals(clientId, that.clientId)
|
||||
&& Objects.equals(applicationData, that.applicationData) && Objects.equals(gmtCreate, that.gmtCreate)
|
||||
&& Objects.equals(gmtModified, that.gmtModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
BranchSessionVO that = (BranchSessionVO) o;
|
||||
return Objects.equals(xid, that.xid)
|
||||
&& Objects.equals(transactionId, that.transactionId)
|
||||
&& Objects.equals(branchId, that.branchId)
|
||||
&& Objects.equals(resourceGroupId, that.resourceGroupId)
|
||||
&& Objects.equals(resourceId, that.resourceId)
|
||||
&& Objects.equals(branchType, that.branchType)
|
||||
&& Objects.equals(status, that.status)
|
||||
&& Objects.equals(clientId, that.clientId)
|
||||
&& Objects.equals(applicationData, that.applicationData)
|
||||
&& Objects.equals(gmtCreate, that.gmtCreate)
|
||||
&& Objects.equals(gmtModified, that.gmtModified);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(xid, transactionId, branchId, resourceGroupId, resourceId, branchType, status, clientId,
|
||||
applicationData, gmtCreate, gmtModified);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(xid,
|
||||
transactionId,
|
||||
branchId,
|
||||
resourceGroupId,
|
||||
resourceId,
|
||||
branchType,
|
||||
status,
|
||||
clientId,
|
||||
applicationData,
|
||||
gmtCreate,
|
||||
gmtModified);
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BranchSessionVO{" + "xid='" + xid + '\'' + ", transactionId=" + transactionId + ", branchId=" + branchId
|
||||
+ ", resourceGroupId='" + resourceGroupId + '\'' + ", resourceId='" + resourceId + '\''
|
||||
+ ", branchType='" + branchType + '\'' + ", status=" + status + ", clientId='" + clientId + '\''
|
||||
+ ", applicationData='" + applicationData + '\'' + ", gmtCreate=" + gmtCreate + ", gmtModified="
|
||||
+ gmtModified + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BranchSessionVO{" +
|
||||
"xid='" + xid + '\'' +
|
||||
", transactionId=" + transactionId +
|
||||
", branchId=" + branchId +
|
||||
", resourceGroupId='" + resourceGroupId + '\'' +
|
||||
", resourceId='" + resourceId + '\'' +
|
||||
", branchType='" + branchType + '\'' +
|
||||
", status=" + status +
|
||||
", clientId='" + clientId + '\'' +
|
||||
", applicationData='" + applicationData + '\'' +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModified=" + gmtModified +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+120
-128
@@ -28,169 +28,161 @@ import java.util.List;
|
||||
|
||||
/**
|
||||
* GlobalLockVO
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
* @author miaoxueyu
|
||||
*/
|
||||
public class GlobalLockVO {
|
||||
|
||||
private String xid;
|
||||
private String xid;
|
||||
|
||||
private String transactionId;
|
||||
private String transactionId;
|
||||
|
||||
private String branchId;
|
||||
private String branchId;
|
||||
|
||||
private String resourceId;
|
||||
private String resourceId;
|
||||
|
||||
private String tableName;
|
||||
private String tableName;
|
||||
|
||||
private String pk;
|
||||
private String pk;
|
||||
|
||||
private String rowKey;
|
||||
private String rowKey;
|
||||
|
||||
private Long gmtCreate;
|
||||
private Long gmtCreate;
|
||||
|
||||
private Long gmtModified;
|
||||
private Long gmtModified;
|
||||
|
||||
/**
|
||||
* convert RowLock list to GlobalLockVO list
|
||||
* @param rowLocks the RowLock list
|
||||
* @return the GlobalLockVO list
|
||||
*/
|
||||
public static List<GlobalLockVO> convert(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<GlobalLockVO> result = new ArrayList<>(rowLocks.size());
|
||||
for (RowLock rowLock : rowLocks) {
|
||||
result.add(convert(rowLock));
|
||||
}
|
||||
/**
|
||||
* convert RowLock list to GlobalLockVO list
|
||||
* @param rowLocks the RowLock list
|
||||
* @return the GlobalLockVO list
|
||||
*/
|
||||
public static List<GlobalLockVO> convert(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final List<GlobalLockVO> result = new ArrayList<>(rowLocks.size());
|
||||
for (RowLock rowLock : rowLocks) {
|
||||
result.add(convert(rowLock));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert RowLock to GlobalLockVO
|
||||
* @param rowLock the RowLock
|
||||
* @return the GlobalLockVO
|
||||
*/
|
||||
public static GlobalLockVO convert(RowLock rowLock) {
|
||||
final GlobalLockVO globalLockVO = new GlobalLockVO();
|
||||
globalLockVO.setXid(rowLock.getXid());
|
||||
globalLockVO.setTransactionId(rowLock.getTransactionId());
|
||||
globalLockVO.setBranchId(rowLock.getBranchId());
|
||||
globalLockVO.setResourceId(rowLock.getResourceId());
|
||||
globalLockVO.setTableName(rowLock.getTableName());
|
||||
globalLockVO.setPk(rowLock.getPk());
|
||||
globalLockVO.setRowKey(rowLock.getRowKey());
|
||||
return globalLockVO;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert RowLock to GlobalLockVO
|
||||
* @param rowLock the RowLock
|
||||
* @return the GlobalLockVO
|
||||
*/
|
||||
public static GlobalLockVO convert(RowLock rowLock) {
|
||||
final GlobalLockVO globalLockVO = new GlobalLockVO();
|
||||
globalLockVO.setXid(rowLock.getXid());
|
||||
globalLockVO.setTransactionId(rowLock.getTransactionId());
|
||||
globalLockVO.setBranchId(rowLock.getBranchId());
|
||||
globalLockVO.setResourceId(rowLock.getResourceId());
|
||||
globalLockVO.setTableName(rowLock.getTableName());
|
||||
globalLockVO.setPk(rowLock.getPk());
|
||||
globalLockVO.setRowKey(rowLock.getRowKey());
|
||||
return globalLockVO;
|
||||
}
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
public void setBranchId(Long branchId) {
|
||||
this.branchId = String.valueOf(branchId);
|
||||
}
|
||||
|
||||
public String getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
public void setBranchId(Long branchId) {
|
||||
this.branchId = String.valueOf(branchId);
|
||||
}
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
public String getPk() {
|
||||
return pk;
|
||||
}
|
||||
|
||||
public void setTableName(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
public void setPk(String pk) {
|
||||
this.pk = pk;
|
||||
}
|
||||
|
||||
public String getPk() {
|
||||
return pk;
|
||||
}
|
||||
public String getRowKey() {
|
||||
return rowKey;
|
||||
}
|
||||
|
||||
public void setPk(String pk) {
|
||||
this.pk = pk;
|
||||
}
|
||||
public void setRowKey(String rowKey) {
|
||||
this.rowKey = rowKey;
|
||||
}
|
||||
|
||||
public String getRowKey() {
|
||||
return rowKey;
|
||||
}
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public void setRowKey(String rowKey) {
|
||||
this.rowKey = rowKey;
|
||||
}
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
public static GlobalLockVO convert(ResultSet rs) throws SQLException {
|
||||
GlobalLockVO globalLockVO = new GlobalLockVO();
|
||||
globalLockVO.setRowKey(rs.getString(ServerTableColumnsName.LOCK_TABLE_ROW_KEY));
|
||||
globalLockVO.setXid(rs.getString(ServerTableColumnsName.LOCK_TABLE_XID));
|
||||
globalLockVO.setTransactionId(rs.getLong(ServerTableColumnsName.LOCK_TABLE_TRANSACTION_ID));
|
||||
globalLockVO.setBranchId(rs.getLong(ServerTableColumnsName.LOCK_TABLE_BRANCH_ID));
|
||||
globalLockVO.setResourceId(rs.getString(ServerTableColumnsName.LOCK_TABLE_RESOURCE_ID));
|
||||
globalLockVO.setTableName(rs.getString(ServerTableColumnsName.LOCK_TABLE_TABLE_NAME));
|
||||
globalLockVO.setPk(rs.getString(ServerTableColumnsName.LOCK_TABLE_PK));
|
||||
Timestamp gmtCreateTimestamp = rs.getTimestamp(ServerTableColumnsName.LOCK_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
globalLockVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Timestamp gmtModifiedTimestamp = rs.getTimestamp(ServerTableColumnsName.LOCK_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
globalLockVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return globalLockVO;
|
||||
}
|
||||
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalLockVO{" + "xid='" + xid + '\'' + ", transactionId=" + transactionId + ", branchId=" + branchId
|
||||
+ ", resourceId='" + resourceId + '\'' + ", tableName='" + tableName + '\'' + ", pk='" + pk + '\''
|
||||
+ ", rowKey='" + rowKey + '\'' + ", gmtCreate=" + gmtCreate + ", gmtModified=" + gmtModified + '}';
|
||||
}
|
||||
|
||||
public static GlobalLockVO convert(ResultSet rs) throws SQLException {
|
||||
GlobalLockVO globalLockVO = new GlobalLockVO();
|
||||
globalLockVO.setRowKey(rs.getString(ServerTableColumnsName.LOCK_TABLE_ROW_KEY));
|
||||
globalLockVO.setXid(rs.getString(ServerTableColumnsName.LOCK_TABLE_XID));
|
||||
globalLockVO.setTransactionId(rs.getLong(ServerTableColumnsName.LOCK_TABLE_TRANSACTION_ID));
|
||||
globalLockVO.setBranchId(rs.getLong(ServerTableColumnsName.LOCK_TABLE_BRANCH_ID));
|
||||
globalLockVO.setResourceId(rs.getString(ServerTableColumnsName.LOCK_TABLE_RESOURCE_ID));
|
||||
globalLockVO.setTableName(rs.getString(ServerTableColumnsName.LOCK_TABLE_TABLE_NAME));
|
||||
globalLockVO.setPk(rs.getString(ServerTableColumnsName.LOCK_TABLE_PK));
|
||||
Timestamp gmtCreateTimestamp = rs.getTimestamp(ServerTableColumnsName.LOCK_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
globalLockVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Timestamp gmtModifiedTimestamp = rs.getTimestamp(ServerTableColumnsName.LOCK_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
globalLockVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return globalLockVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalLockVO{" +
|
||||
"xid='" + xid + '\'' +
|
||||
", transactionId=" + transactionId +
|
||||
", branchId=" + branchId +
|
||||
", resourceId='" + resourceId + '\'' +
|
||||
", tableName='" + tableName + '\'' +
|
||||
", pk='" + pk + '\'' +
|
||||
", rowKey='" + rowKey + '\'' +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModified=" + gmtModified +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+131
-145
@@ -24,194 +24,180 @@ import java.util.Set;
|
||||
|
||||
/**
|
||||
* GlobalSessionVO
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class GlobalSessionVO {
|
||||
|
||||
private String xid;
|
||||
private String xid;
|
||||
|
||||
private String transactionId;
|
||||
private String transactionId;
|
||||
|
||||
private Integer status;
|
||||
private Integer status;
|
||||
|
||||
private String applicationId;
|
||||
private String applicationId;
|
||||
|
||||
private String transactionServiceGroup;
|
||||
private String transactionServiceGroup;
|
||||
|
||||
private String transactionName;
|
||||
private String transactionName;
|
||||
|
||||
private Long timeout;
|
||||
private Long timeout;
|
||||
|
||||
private Long beginTime;
|
||||
private Long beginTime;
|
||||
|
||||
private String applicationData;
|
||||
private String applicationData;
|
||||
|
||||
private Long gmtCreate;
|
||||
private Long gmtCreate;
|
||||
|
||||
private Long gmtModified;
|
||||
private Long gmtModified;
|
||||
|
||||
private Set<BranchSessionVO> branchSessionVOs;
|
||||
private Set<BranchSessionVO> branchSessionVOs;
|
||||
|
||||
public GlobalSessionVO() {
|
||||
|
||||
public GlobalSessionVO() {
|
||||
}
|
||||
|
||||
}
|
||||
public GlobalSessionVO(String xid, Long transactionId, Integer status, String applicationId,
|
||||
String transactionServiceGroup, String transactionName, Long timeout, Long beginTime,
|
||||
String applicationData, Set<BranchSessionVO> branchSessionVOs) {
|
||||
this.xid = xid;
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
this.status = status;
|
||||
this.applicationId = applicationId;
|
||||
this.transactionServiceGroup = transactionServiceGroup;
|
||||
this.transactionName = transactionName;
|
||||
this.timeout = timeout;
|
||||
this.beginTime = beginTime;
|
||||
this.applicationData = applicationData;
|
||||
this.branchSessionVOs = branchSessionVOs;
|
||||
}
|
||||
|
||||
public GlobalSessionVO(String xid,
|
||||
Long transactionId,
|
||||
Integer status,
|
||||
String applicationId,
|
||||
String transactionServiceGroup,
|
||||
String transactionName,
|
||||
Long timeout,
|
||||
Long beginTime,
|
||||
String applicationData,
|
||||
Set<BranchSessionVO> branchSessionVOs) {
|
||||
this.xid = xid;
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
this.status = status;
|
||||
this.applicationId = applicationId;
|
||||
this.transactionServiceGroup = transactionServiceGroup;
|
||||
this.transactionName = transactionName;
|
||||
this.timeout = timeout;
|
||||
this.beginTime = beginTime;
|
||||
this.applicationData = applicationData;
|
||||
this.branchSessionVOs = branchSessionVOs;
|
||||
}
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public String getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = String.valueOf(transactionId);
|
||||
}
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Integer getStatus() {
|
||||
return status;
|
||||
}
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public void setStatus(Integer status) {
|
||||
this.status = status;
|
||||
}
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
|
||||
public String getApplicationId() {
|
||||
return applicationId;
|
||||
}
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
|
||||
public void setApplicationId(String applicationId) {
|
||||
this.applicationId = applicationId;
|
||||
}
|
||||
public String getTransactionServiceGroup() {
|
||||
return transactionServiceGroup;
|
||||
}
|
||||
|
||||
public String getTransactionServiceGroup() {
|
||||
return transactionServiceGroup;
|
||||
}
|
||||
public void setTransactionServiceGroup(String transactionServiceGroup) {
|
||||
this.transactionServiceGroup = transactionServiceGroup;
|
||||
}
|
||||
|
||||
public void setTransactionServiceGroup(String transactionServiceGroup) {
|
||||
this.transactionServiceGroup = transactionServiceGroup;
|
||||
}
|
||||
public String getTransactionName() {
|
||||
return transactionName;
|
||||
}
|
||||
|
||||
public String getTransactionName() {
|
||||
return transactionName;
|
||||
}
|
||||
public void setTransactionName(String transactionName) {
|
||||
this.transactionName = transactionName;
|
||||
}
|
||||
|
||||
public void setTransactionName(String transactionName) {
|
||||
this.transactionName = transactionName;
|
||||
}
|
||||
public Long getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
public Long getTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
public void setTimeout(Long timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public void setTimeout(Long timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
public Long getBeginTime() {
|
||||
return beginTime;
|
||||
}
|
||||
|
||||
public Long getBeginTime() {
|
||||
return beginTime;
|
||||
}
|
||||
public void setBeginTime(Long beginTime) {
|
||||
this.beginTime = beginTime;
|
||||
}
|
||||
|
||||
public void setBeginTime(Long beginTime) {
|
||||
this.beginTime = beginTime;
|
||||
}
|
||||
public String getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
|
||||
public String getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
public void setApplicationData(String applicationData) {
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
|
||||
public void setApplicationData(String applicationData) {
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
|
||||
public Long getGmtCreate() {
|
||||
return gmtCreate;
|
||||
}
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
|
||||
public void setGmtCreate(Long gmtCreate) {
|
||||
this.gmtCreate = gmtCreate;
|
||||
}
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
|
||||
public Long getGmtModified() {
|
||||
return gmtModified;
|
||||
}
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
|
||||
public void setGmtModified(Long gmtModified) {
|
||||
this.gmtModified = gmtModified;
|
||||
}
|
||||
public Set<BranchSessionVO> getBranchSessionVOs() {
|
||||
return branchSessionVOs;
|
||||
}
|
||||
|
||||
public Set<BranchSessionVO> getBranchSessionVOs() {
|
||||
return branchSessionVOs;
|
||||
}
|
||||
public void setBranchSessionVOs(Set<BranchSessionVO> branchSessionVOs) {
|
||||
this.branchSessionVOs = branchSessionVOs;
|
||||
}
|
||||
|
||||
public void setBranchSessionVOs(Set<BranchSessionVO> branchSessionVOs) {
|
||||
this.branchSessionVOs = branchSessionVOs;
|
||||
}
|
||||
public static GlobalSessionVO convert(ResultSet rs) throws SQLException {
|
||||
GlobalSessionVO globalSessionVO = new GlobalSessionVO();
|
||||
globalSessionVO.setXid(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_XID));
|
||||
globalSessionVO.setTransactionId(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_ID));
|
||||
globalSessionVO.setStatus(rs.getInt(ServerTableColumnsName.GLOBAL_TABLE_STATUS));
|
||||
globalSessionVO.setApplicationId(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_APPLICATION_ID));
|
||||
globalSessionVO.setTransactionServiceGroup(
|
||||
rs.getString(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_SERVICE_GROUP));
|
||||
globalSessionVO.setTransactionName(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_NAME));
|
||||
globalSessionVO.setTimeout(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_TIMEOUT));
|
||||
globalSessionVO.setBeginTime(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_BEGIN_TIME));
|
||||
globalSessionVO.setApplicationData(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_APPLICATION_DATA));
|
||||
Timestamp gmtCreateTimestamp = rs.getTimestamp(ServerTableColumnsName.GLOBAL_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
globalSessionVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Timestamp gmtModifiedTimestamp = rs.getTimestamp(ServerTableColumnsName.GLOBAL_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
globalSessionVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return globalSessionVO;
|
||||
}
|
||||
|
||||
public static GlobalSessionVO convert(ResultSet rs) throws SQLException {
|
||||
GlobalSessionVO globalSessionVO = new GlobalSessionVO();
|
||||
globalSessionVO.setXid(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_XID));
|
||||
globalSessionVO.setTransactionId(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_ID));
|
||||
globalSessionVO.setStatus(rs.getInt(ServerTableColumnsName.GLOBAL_TABLE_STATUS));
|
||||
globalSessionVO.setApplicationId(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_APPLICATION_ID));
|
||||
globalSessionVO.setTransactionServiceGroup(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_SERVICE_GROUP));
|
||||
globalSessionVO.setTransactionName(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_TRANSACTION_NAME));
|
||||
globalSessionVO.setTimeout(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_TIMEOUT));
|
||||
globalSessionVO.setBeginTime(rs.getLong(ServerTableColumnsName.GLOBAL_TABLE_BEGIN_TIME));
|
||||
globalSessionVO.setApplicationData(rs.getString(ServerTableColumnsName.GLOBAL_TABLE_APPLICATION_DATA));
|
||||
Timestamp gmtCreateTimestamp = rs.getTimestamp(ServerTableColumnsName.GLOBAL_TABLE_GMT_CREATE);
|
||||
if (gmtCreateTimestamp != null) {
|
||||
globalSessionVO.setGmtCreate(gmtCreateTimestamp.getTime());
|
||||
}
|
||||
Timestamp gmtModifiedTimestamp = rs.getTimestamp(ServerTableColumnsName.GLOBAL_TABLE_GMT_MODIFIED);
|
||||
if (gmtModifiedTimestamp != null) {
|
||||
globalSessionVO.setGmtModified(gmtModifiedTimestamp.getTime());
|
||||
}
|
||||
return globalSessionVO;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalSessionVO{" + "xid='" + xid + '\'' + ", transactionId=" + transactionId + ", status=" + status
|
||||
+ ", applicationId='" + applicationId + '\'' + ", transactionServiceGroup='" + transactionServiceGroup
|
||||
+ '\'' + ", transactionName='" + transactionName + '\'' + ", timeout=" + timeout + ", beginTime="
|
||||
+ beginTime + ", applicationData='" + applicationData + '\'' + ", gmtCreate=" + gmtCreate
|
||||
+ ", gmtModified=" + gmtModified + ", branchSessionVOs=" + branchSessionVOs + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "GlobalSessionVO{" +
|
||||
"xid='" + xid + '\'' +
|
||||
", transactionId=" + transactionId +
|
||||
", status=" + status +
|
||||
", applicationId='" + applicationId + '\'' +
|
||||
", transactionServiceGroup='" + transactionServiceGroup + '\'' +
|
||||
", transactionName='" + transactionName + '\'' +
|
||||
", timeout=" + timeout +
|
||||
", beginTime=" + beginTime +
|
||||
", applicationData='" + applicationData + '\'' +
|
||||
", gmtCreate=" + gmtCreate +
|
||||
", gmtModified=" + gmtModified +
|
||||
", branchSessionVOs=" + branchSessionVOs +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
+10
-9
@@ -28,16 +28,17 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
||||
@RequestMapping
|
||||
public class HealthController {
|
||||
|
||||
private static final String OK = "ok";
|
||||
private static final String NOT_OK = "not_ok";
|
||||
private static final String OK = "ok";
|
||||
|
||||
@Autowired
|
||||
private ServerRunner serverRunner;
|
||||
private static final String NOT_OK = "not_ok";
|
||||
|
||||
@Autowired
|
||||
private ServerRunner serverRunner;
|
||||
|
||||
@RequestMapping("/health")
|
||||
@ResponseBody
|
||||
String healthCheck() {
|
||||
return serverRunner.started() ? OK : NOT_OK;
|
||||
}
|
||||
|
||||
@RequestMapping("/health")
|
||||
@ResponseBody
|
||||
String healthCheck() {
|
||||
return serverRunner.started() ? OK : NOT_OK;
|
||||
}
|
||||
}
|
||||
+171
-159
@@ -50,190 +50,202 @@ import static io.seata.core.exception.TransactionExceptionCode.*;
|
||||
*/
|
||||
public abstract class AbstractCore implements Core {
|
||||
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractCore.class);
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractCore.class);
|
||||
|
||||
protected LockManager lockManager = LockerManagerFactory.getLockManager();
|
||||
protected LockManager lockManager = LockerManagerFactory.getLockManager();
|
||||
|
||||
protected RemotingServer remotingServer;
|
||||
protected RemotingServer remotingServer;
|
||||
|
||||
public AbstractCore(RemotingServer remotingServer) {
|
||||
if (remotingServer == null) {
|
||||
throw new IllegalArgumentException("remotingServer must be not null");
|
||||
}
|
||||
this.remotingServer = remotingServer;
|
||||
}
|
||||
public AbstractCore(RemotingServer remotingServer) {
|
||||
if (remotingServer == null) {
|
||||
throw new IllegalArgumentException("remotingServer must be not null");
|
||||
}
|
||||
this.remotingServer = remotingServer;
|
||||
}
|
||||
|
||||
public abstract BranchType getHandleBranchType();
|
||||
public abstract BranchType getHandleBranchType();
|
||||
|
||||
@Override
|
||||
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
|
||||
String applicationData, String lockKeys) throws TransactionException {
|
||||
GlobalSession globalSession = assertGlobalSessionNotNull(xid, false);
|
||||
return SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
globalSessionStatusCheck(globalSession);
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, branchType, resourceId,
|
||||
applicationData, lockKeys, clientId);
|
||||
MDC.put(RootContext.MDC_KEY_BRANCH_ID, String.valueOf(branchSession.getBranchId()));
|
||||
branchSessionLock(globalSession, branchSession);
|
||||
try {
|
||||
globalSession.addBranch(branchSession);
|
||||
} catch (RuntimeException ex) {
|
||||
branchSessionUnlock(branchSession);
|
||||
throw new BranchTransactionException(FailedToAddBranch, String
|
||||
.format("Failed to store branch xid = %s branchId = %s", globalSession.getXid(),
|
||||
branchSession.getBranchId()), ex);
|
||||
}
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Register branch successfully, xid = {}, branchId = {}, resourceId = {} ,lockKeys = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId(), resourceId, lockKeys);
|
||||
}
|
||||
return branchSession.getBranchId();
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
|
||||
String applicationData, String lockKeys) throws TransactionException {
|
||||
GlobalSession globalSession = assertGlobalSessionNotNull(xid, false);
|
||||
return SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
globalSessionStatusCheck(globalSession);
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
BranchSession branchSession = SessionHelper.newBranchByGlobal(globalSession, branchType, resourceId,
|
||||
applicationData, lockKeys, clientId);
|
||||
MDC.put(RootContext.MDC_KEY_BRANCH_ID, String.valueOf(branchSession.getBranchId()));
|
||||
branchSessionLock(globalSession, branchSession);
|
||||
try {
|
||||
globalSession.addBranch(branchSession);
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
branchSessionUnlock(branchSession);
|
||||
throw new BranchTransactionException(FailedToAddBranch,
|
||||
String.format("Failed to store branch xid = %s branchId = %s", globalSession.getXid(),
|
||||
branchSession.getBranchId()),
|
||||
ex);
|
||||
}
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Register branch successfully, xid = {}, branchId = {}, resourceId = {} ,lockKeys = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId(), resourceId, lockKeys);
|
||||
}
|
||||
return branchSession.getBranchId();
|
||||
});
|
||||
}
|
||||
|
||||
protected void globalSessionStatusCheck(GlobalSession globalSession) throws GlobalTransactionException {
|
||||
if (!globalSession.isActive()) {
|
||||
throw new GlobalTransactionException(GlobalTransactionNotActive, String.format(
|
||||
"Could not register branch into global session xid = %s status = %s, cause by globalSession not active",
|
||||
globalSession.getXid(), globalSession.getStatus()));
|
||||
}
|
||||
if (globalSession.getStatus() != GlobalStatus.Begin) {
|
||||
throw new GlobalTransactionException(GlobalTransactionStatusInvalid, String
|
||||
.format("Could not register branch into global session xid = %s status = %s while expecting %s",
|
||||
globalSession.getXid(), globalSession.getStatus(), GlobalStatus.Begin));
|
||||
}
|
||||
}
|
||||
protected void globalSessionStatusCheck(GlobalSession globalSession) throws GlobalTransactionException {
|
||||
if (!globalSession.isActive()) {
|
||||
throw new GlobalTransactionException(GlobalTransactionNotActive, String.format(
|
||||
"Could not register branch into global session xid = %s status = %s, cause by globalSession not active",
|
||||
globalSession.getXid(), globalSession.getStatus()));
|
||||
}
|
||||
if (globalSession.getStatus() != GlobalStatus.Begin) {
|
||||
throw new GlobalTransactionException(GlobalTransactionStatusInvalid,
|
||||
String.format(
|
||||
"Could not register branch into global session xid = %s status = %s while expecting %s",
|
||||
globalSession.getXid(), globalSession.getStatus(), GlobalStatus.Begin));
|
||||
}
|
||||
}
|
||||
|
||||
protected void branchSessionLock(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
protected void branchSessionLock(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected void branchSessionUnlock(BranchSession branchSession) throws TransactionException {
|
||||
protected void branchSessionUnlock(BranchSession branchSession) throws TransactionException {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private GlobalSession assertGlobalSessionNotNull(String xid, boolean withBranchSessions)
|
||||
throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid, withBranchSessions);
|
||||
if (globalSession == null) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.GlobalTransactionNotExist,
|
||||
String.format("Could not found global transaction xid = %s, may be has finished.", xid));
|
||||
}
|
||||
return globalSession;
|
||||
}
|
||||
private GlobalSession assertGlobalSessionNotNull(String xid, boolean withBranchSessions)
|
||||
throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid, withBranchSessions);
|
||||
if (globalSession == null) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.GlobalTransactionNotExist,
|
||||
String.format("Could not found global transaction xid = %s, may be has finished.", xid));
|
||||
}
|
||||
return globalSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
|
||||
String applicationData) throws TransactionException {
|
||||
GlobalSession globalSession = assertGlobalSessionNotNull(xid, true);
|
||||
BranchSession branchSession = globalSession.getBranch(branchId);
|
||||
if (branchSession == null) {
|
||||
throw new BranchTransactionException(BranchTransactionNotExist,
|
||||
String.format("Could not found branch session xid = %s branchId = %s", xid, branchId));
|
||||
}
|
||||
branchSession.setApplicationData(applicationData);
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
globalSession.changeBranchStatus(branchSession, status);
|
||||
@Override
|
||||
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
|
||||
String applicationData) throws TransactionException {
|
||||
GlobalSession globalSession = assertGlobalSessionNotNull(xid, true);
|
||||
BranchSession branchSession = globalSession.getBranch(branchId);
|
||||
if (branchSession == null) {
|
||||
throw new BranchTransactionException(BranchTransactionNotExist,
|
||||
String.format("Could not found branch session xid = %s branchId = %s", xid, branchId));
|
||||
}
|
||||
branchSession.setApplicationData(applicationData);
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
globalSession.changeBranchStatus(branchSession, status);
|
||||
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Report branch status successfully, xid = {}, branchId = {}", globalSession.getXid(),
|
||||
branchSession.getBranchId());
|
||||
}
|
||||
}
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Report branch status successfully, xid = {}, branchId = {}", globalSession.getXid(),
|
||||
branchSession.getBranchId());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
|
||||
throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
|
||||
throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
try {
|
||||
BranchCommitRequest request = new BranchCommitRequest();
|
||||
request.setXid(branchSession.getXid());
|
||||
request.setBranchId(branchSession.getBranchId());
|
||||
request.setResourceId(branchSession.getResourceId());
|
||||
request.setApplicationData(branchSession.getApplicationData());
|
||||
request.setBranchType(branchSession.getBranchType());
|
||||
return branchCommitSend(request, globalSession, branchSession);
|
||||
} catch (IOException | TimeoutException e) {
|
||||
throw new BranchTransactionException(FailedToSendBranchCommitRequest,
|
||||
String.format("Send branch commit failed, xid = %s branchId = %s", branchSession.getXid(),
|
||||
branchSession.getBranchId()), e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
try {
|
||||
BranchCommitRequest request = new BranchCommitRequest();
|
||||
request.setXid(branchSession.getXid());
|
||||
request.setBranchId(branchSession.getBranchId());
|
||||
request.setResourceId(branchSession.getResourceId());
|
||||
request.setApplicationData(branchSession.getApplicationData());
|
||||
request.setBranchType(branchSession.getBranchType());
|
||||
return branchCommitSend(request, globalSession, branchSession);
|
||||
}
|
||||
catch (IOException | TimeoutException e) {
|
||||
throw new BranchTransactionException(FailedToSendBranchCommitRequest,
|
||||
String.format("Send branch commit failed, xid = %s branchId = %s", branchSession.getXid(),
|
||||
branchSession.getBranchId()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
protected BranchStatus branchCommitSend(BranchCommitRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
BranchCommitResponse response = (BranchCommitResponse) remotingServer.sendSyncRequest(
|
||||
branchSession.getResourceId(), branchSession.getClientId(), request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
protected BranchStatus branchCommitSend(BranchCommitRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
BranchCommitResponse response = (BranchCommitResponse) remotingServer
|
||||
.sendSyncRequest(branchSession.getResourceId(), branchSession.getClientId(), request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
try {
|
||||
BranchRollbackRequest request = new BranchRollbackRequest();
|
||||
request.setXid(branchSession.getXid());
|
||||
request.setBranchId(branchSession.getBranchId());
|
||||
request.setResourceId(branchSession.getResourceId());
|
||||
request.setApplicationData(branchSession.getApplicationData());
|
||||
request.setBranchType(branchSession.getBranchType());
|
||||
return branchRollbackSend(request, globalSession, branchSession);
|
||||
} catch (IOException | TimeoutException e) {
|
||||
throw new BranchTransactionException(FailedToSendBranchRollbackRequest,
|
||||
String.format("Send branch rollback failed, xid = %s branchId = %s",
|
||||
branchSession.getXid(), branchSession.getBranchId()), e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
try {
|
||||
BranchRollbackRequest request = new BranchRollbackRequest();
|
||||
request.setXid(branchSession.getXid());
|
||||
request.setBranchId(branchSession.getBranchId());
|
||||
request.setResourceId(branchSession.getResourceId());
|
||||
request.setApplicationData(branchSession.getApplicationData());
|
||||
request.setBranchType(branchSession.getBranchType());
|
||||
return branchRollbackSend(request, globalSession, branchSession);
|
||||
}
|
||||
catch (IOException | TimeoutException e) {
|
||||
throw new BranchTransactionException(FailedToSendBranchRollbackRequest,
|
||||
String.format("Send branch rollback failed, xid = %s branchId = %s", branchSession.getXid(),
|
||||
branchSession.getBranchId()),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
protected BranchStatus branchRollbackSend(BranchRollbackRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
BranchRollbackResponse response = (BranchRollbackResponse) remotingServer.sendSyncRequest(
|
||||
branchSession.getResourceId(), branchSession.getClientId(), request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
protected BranchStatus branchRollbackSend(BranchRollbackRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
BranchRollbackResponse response = (BranchRollbackResponse) remotingServer
|
||||
.sendSyncRequest(branchSession.getResourceId(), branchSession.getClientId(), request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout)
|
||||
throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout)
|
||||
throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus commit(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public GlobalStatus commit(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus globalReport(String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public GlobalStatus globalReport(String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus rollback(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public GlobalStatus rollback(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus getStatus(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public GlobalStatus getStatus(String xid) throws TransactionException {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
@Override
|
||||
public void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus globalStatus)
|
||||
throws TransactionException {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -26,34 +26,31 @@ import io.seata.server.session.GlobalSession;
|
||||
*/
|
||||
public interface Core extends TransactionCoordinatorInbound, TransactionCoordinatorOutbound {
|
||||
|
||||
/**
|
||||
* Do global commit.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retrying the retrying
|
||||
* @return is global commit.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException;
|
||||
/**
|
||||
* Do global commit.
|
||||
* @param globalSession the global session
|
||||
* @param retrying the retrying
|
||||
* @return is global commit.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Do global rollback.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retrying the retrying
|
||||
* @return is global rollback.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException;
|
||||
/**
|
||||
* Do global rollback.
|
||||
* @param globalSession the global session
|
||||
* @param retrying the retrying
|
||||
* @return is global rollback.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Do global report.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param xid Transaction id.
|
||||
* @param param the global status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus param) throws TransactionException;
|
||||
/**
|
||||
* Do global report.
|
||||
* @param globalSession the global session
|
||||
* @param xid Transaction id.
|
||||
* @param param the global status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus param) throws TransactionException;
|
||||
|
||||
}
|
||||
+554
-537
File diff suppressed because it is too large.
Load diff
+338
-312
@@ -50,349 +50,375 @@ import static io.seata.server.session.BranchSessionHandler.CONTINUE;
|
||||
*/
|
||||
public class DefaultCore implements Core {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCore.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultCore.class);
|
||||
|
||||
private static final int RETRY_XAER_NOTA_TIMEOUT = ConfigurationFactory.getInstance().getInt(XAER_NOTA_RETRY_TIMEOUT,
|
||||
DefaultValues.DEFAULT_XAER_NOTA_RETRY_TIMEOUT);
|
||||
private static final int RETRY_XAER_NOTA_TIMEOUT = ConfigurationFactory.getInstance()
|
||||
.getInt(XAER_NOTA_RETRY_TIMEOUT, DefaultValues.DEFAULT_XAER_NOTA_RETRY_TIMEOUT);
|
||||
|
||||
private static Map<BranchType, AbstractCore> coreMap = new ConcurrentHashMap<>();
|
||||
private static Map<BranchType, AbstractCore> coreMap = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* get the Default core.
|
||||
*
|
||||
* @param remotingServer the remoting server
|
||||
*/
|
||||
public DefaultCore(RemotingServer remotingServer) {
|
||||
List<AbstractCore> allCore = EnhancedServiceLoader.loadAll(AbstractCore.class,
|
||||
new Class[] {RemotingServer.class}, new Object[] {remotingServer});
|
||||
if (CollectionUtils.isNotEmpty(allCore)) {
|
||||
for (AbstractCore core : allCore) {
|
||||
coreMap.put(core.getHandleBranchType(), core);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* get the Default core.
|
||||
* @param remotingServer the remoting server
|
||||
*/
|
||||
public DefaultCore(RemotingServer remotingServer) {
|
||||
List<AbstractCore> allCore = EnhancedServiceLoader.loadAll(AbstractCore.class,
|
||||
new Class[] { RemotingServer.class }, new Object[] { remotingServer });
|
||||
if (CollectionUtils.isNotEmpty(allCore)) {
|
||||
for (AbstractCore core : allCore) {
|
||||
coreMap.put(core.getHandleBranchType(), core);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get core
|
||||
*
|
||||
* @param branchType the branchType
|
||||
* @return the core
|
||||
*/
|
||||
public AbstractCore getCore(BranchType branchType) {
|
||||
AbstractCore core = coreMap.get(branchType);
|
||||
if (core == null) {
|
||||
throw new NotSupportYetException("unsupported type:" + branchType.name());
|
||||
}
|
||||
return core;
|
||||
}
|
||||
/**
|
||||
* get core
|
||||
* @param branchType the branchType
|
||||
* @return the core
|
||||
*/
|
||||
public AbstractCore getCore(BranchType branchType) {
|
||||
AbstractCore core = coreMap.get(branchType);
|
||||
if (core == null) {
|
||||
throw new NotSupportYetException("unsupported type:" + branchType.name());
|
||||
}
|
||||
return core;
|
||||
}
|
||||
|
||||
/**
|
||||
* only for mock
|
||||
*
|
||||
* @param branchType the branchType
|
||||
* @param core the core
|
||||
*/
|
||||
public void mockCore(BranchType branchType, AbstractCore core) {
|
||||
coreMap.put(branchType, core);
|
||||
}
|
||||
/**
|
||||
* only for mock
|
||||
* @param branchType the branchType
|
||||
* @param core the core
|
||||
*/
|
||||
public void mockCore(BranchType branchType, AbstractCore core) {
|
||||
coreMap.put(branchType, core);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
|
||||
String applicationData, String lockKeys) throws TransactionException {
|
||||
return getCore(branchType).branchRegister(branchType, resourceId, clientId, xid,
|
||||
applicationData, lockKeys);
|
||||
}
|
||||
@Override
|
||||
public Long branchRegister(BranchType branchType, String resourceId, String clientId, String xid,
|
||||
String applicationData, String lockKeys) throws TransactionException {
|
||||
return getCore(branchType).branchRegister(branchType, resourceId, clientId, xid, applicationData, lockKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
|
||||
String applicationData) throws TransactionException {
|
||||
getCore(branchType).branchReport(branchType, xid, branchId, status, applicationData);
|
||||
}
|
||||
@Override
|
||||
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
|
||||
String applicationData) throws TransactionException {
|
||||
getCore(branchType).branchReport(branchType, xid, branchId, status, applicationData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
|
||||
throws TransactionException {
|
||||
return getCore(branchType).lockQuery(branchType, resourceId, xid, lockKeys);
|
||||
}
|
||||
@Override
|
||||
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
|
||||
throws TransactionException {
|
||||
return getCore(branchType).lockQuery(branchType, resourceId, xid, lockKeys);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
return getCore(branchSession.getBranchType()).branchCommit(globalSession, branchSession);
|
||||
}
|
||||
@Override
|
||||
public BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
return getCore(branchSession.getBranchType()).branchCommit(globalSession, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
return getCore(branchSession.getBranchType()).branchRollback(globalSession, branchSession);
|
||||
}
|
||||
@Override
|
||||
public BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
return getCore(branchSession.getBranchType()).branchRollback(globalSession, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout)
|
||||
throws TransactionException {
|
||||
GlobalSession session = GlobalSession.createGlobalSession(applicationId, transactionServiceGroup, name, timeout);
|
||||
MDC.put(RootContext.MDC_KEY_XID, session.getXid());
|
||||
session.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
@Override
|
||||
public String begin(String applicationId, String transactionServiceGroup, String name, int timeout)
|
||||
throws TransactionException {
|
||||
GlobalSession session = GlobalSession.createGlobalSession(applicationId, transactionServiceGroup, name,
|
||||
timeout);
|
||||
MDC.put(RootContext.MDC_KEY_XID, session.getXid());
|
||||
session.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
|
||||
session.begin();
|
||||
session.begin();
|
||||
|
||||
// transaction start event
|
||||
MetricsPublisher.postSessionDoingEvent(session, false);
|
||||
// transaction start event
|
||||
MetricsPublisher.postSessionDoingEvent(session, false);
|
||||
|
||||
return session.getXid();
|
||||
}
|
||||
return session.getXid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus commit(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
}
|
||||
|
||||
if (globalSession.isTimeout()) {
|
||||
LOGGER.info("TC detected timeout, xid = {}", globalSession.getXid());
|
||||
return GlobalStatus.TimeoutRollbacking;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus commit(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
}
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
// just lock changeStatus
|
||||
|
||||
if (globalSession.isTimeout()) {
|
||||
LOGGER.info("TC detected timeout, xid = {}", globalSession.getXid());
|
||||
return GlobalStatus.TimeoutRollbacking;
|
||||
}
|
||||
boolean shouldCommit = SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
if (globalSession.getStatus() == GlobalStatus.Begin) {
|
||||
// Highlight: Firstly, close the session, then no more branch can be
|
||||
// registered.
|
||||
globalSession.closeAndClean();
|
||||
if (globalSession.canBeCommittedAsync()) {
|
||||
globalSession.asyncCommit();
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, GlobalStatus.Committed, false, false);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Committing);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
// just lock changeStatus
|
||||
if (shouldCommit) {
|
||||
boolean success = doGlobalCommit(globalSession, false);
|
||||
// If successful and all remaining branches can be committed asynchronously,
|
||||
// do async commit.
|
||||
if (success && globalSession.hasBranch() && globalSession.canBeCommittedAsync()) {
|
||||
globalSession.asyncCommit();
|
||||
return GlobalStatus.Committed;
|
||||
}
|
||||
else {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return globalSession.getStatus() == GlobalStatus.AsyncCommitting ? GlobalStatus.Committed
|
||||
: globalSession.getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
boolean shouldCommit = SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
if (globalSession.getStatus() == GlobalStatus.Begin) {
|
||||
// Highlight: Firstly, close the session, then no more branch can be registered.
|
||||
globalSession.closeAndClean();
|
||||
if (globalSession.canBeCommittedAsync()) {
|
||||
globalSession.asyncCommit();
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, GlobalStatus.Committed, false, false);
|
||||
return false;
|
||||
} else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Committing);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
@Override
|
||||
public boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
boolean success = true;
|
||||
// start committing event
|
||||
MetricsPublisher.postSessionDoingEvent(globalSession, retrying);
|
||||
|
||||
if (shouldCommit) {
|
||||
boolean success = doGlobalCommit(globalSession, false);
|
||||
//If successful and all remaining branches can be committed asynchronously, do async commit.
|
||||
if (success && globalSession.hasBranch() && globalSession.canBeCommittedAsync()) {
|
||||
globalSession.asyncCommit();
|
||||
return GlobalStatus.Committed;
|
||||
} else {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
} else {
|
||||
return globalSession.getStatus() == GlobalStatus.AsyncCommitting ? GlobalStatus.Committed : globalSession.getStatus();
|
||||
}
|
||||
}
|
||||
if (globalSession.isSaga()) {
|
||||
success = getCore(BranchType.SAGA).doGlobalCommit(globalSession, retrying);
|
||||
}
|
||||
else {
|
||||
Boolean result = SessionHelper.forEach(globalSession.getSortedBranches(), branchSession -> {
|
||||
// if not retrying, skip the canBeCommittedAsync branches
|
||||
if (!retrying && branchSession.canBeCommittedAsync()) {
|
||||
return CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
boolean success = true;
|
||||
// start committing event
|
||||
MetricsPublisher.postSessionDoingEvent(globalSession, retrying);
|
||||
BranchStatus currentStatus = branchSession.getStatus();
|
||||
if (currentStatus == BranchStatus.PhaseOne_Failed) {
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
}
|
||||
try {
|
||||
BranchStatus branchStatus = getCore(branchSession.getBranchType()).branchCommit(globalSession,
|
||||
branchSession);
|
||||
if (isXaerNotaTimeout(globalSession, branchStatus)) {
|
||||
LOGGER.info("Commit branch XAER_NOTA retry timeout, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
branchStatus = BranchStatus.PhaseTwo_Committed;
|
||||
}
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Committed:
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
case PhaseTwo_CommitFailed_Unretryable:
|
||||
// not at branch
|
||||
SessionHelper.endCommitFailed(globalSession, retrying);
|
||||
LOGGER.error(
|
||||
"Committing global transaction[{}] finally failed, caused by branch transaction[{}] commit failed.",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
|
||||
if (globalSession.isSaga()) {
|
||||
success = getCore(BranchType.SAGA).doGlobalCommit(globalSession, retrying);
|
||||
} else {
|
||||
Boolean result = SessionHelper.forEach(globalSession.getSortedBranches(), branchSession -> {
|
||||
// if not retrying, skip the canBeCommittedAsync branches
|
||||
if (!retrying && branchSession.canBeCommittedAsync()) {
|
||||
return CONTINUE;
|
||||
}
|
||||
default:
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryCommit();
|
||||
return false;
|
||||
}
|
||||
if (globalSession.canBeCommittedAsync()) {
|
||||
LOGGER.error("Committing branch transaction[{}], status:{} and will retry later",
|
||||
branchSession.getBranchId(), branchStatus);
|
||||
return CONTINUE;
|
||||
}
|
||||
else {
|
||||
LOGGER.error(
|
||||
"Committing global transaction[{}] failed, caused by branch transaction[{}] commit failed, will retry later.",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
StackTraceLogger.error(LOGGER, ex, "Committing branch transaction exception: {}",
|
||||
new String[] { branchSession.toString() });
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryCommit();
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
}
|
||||
return CONTINUE;
|
||||
});
|
||||
// Return if the result is not null
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
// If has branch and not all remaining branches can be committed
|
||||
// asynchronously,
|
||||
// do print log and return false
|
||||
if (globalSession.hasBranch() && !globalSession.canBeCommittedAsync()) {
|
||||
LOGGER.info("Committing global transaction is NOT done, xid = {}.", globalSession.getXid());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if it succeeds and there is no branch, retrying=true is the asynchronous state
|
||||
// when retrying. EndCommitted is
|
||||
// executed to improve concurrency performance, and the global transaction ends..
|
||||
if (success && globalSession.getBranchSessions().isEmpty()) {
|
||||
if (!retrying) {
|
||||
// contains not AT branch
|
||||
globalSession.setStatus(GlobalStatus.Committed);
|
||||
}
|
||||
SessionHelper.endCommitted(globalSession, retrying);
|
||||
LOGGER.info("Committing global transaction is successfully done, xid = {}.", globalSession.getXid());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
BranchStatus currentStatus = branchSession.getStatus();
|
||||
if (currentStatus == BranchStatus.PhaseOne_Failed) {
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
}
|
||||
try {
|
||||
BranchStatus branchStatus = getCore(branchSession.getBranchType()).branchCommit(globalSession, branchSession);
|
||||
if (isXaerNotaTimeout(globalSession,branchStatus)) {
|
||||
LOGGER.info("Commit branch XAER_NOTA retry timeout, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
|
||||
branchStatus = BranchStatus.PhaseTwo_Committed;
|
||||
}
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Committed:
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
case PhaseTwo_CommitFailed_Unretryable:
|
||||
//not at branch
|
||||
SessionHelper.endCommitFailed(globalSession, retrying);
|
||||
LOGGER.error("Committing global transaction[{}] finally failed, caused by branch transaction[{}] commit failed.", globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
@Override
|
||||
public GlobalStatus rollback(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
}
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
// just lock changeStatus
|
||||
boolean shouldRollBack = SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
globalSession.close(); // Highlight: Firstly, close the session, then no more
|
||||
// branch can be registered.
|
||||
if (globalSession.getStatus() == GlobalStatus.Begin) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Rollbacking);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (!shouldRollBack) {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
|
||||
default:
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryCommit();
|
||||
return false;
|
||||
}
|
||||
if (globalSession.canBeCommittedAsync()) {
|
||||
LOGGER.error("Committing branch transaction[{}], status:{} and will retry later",
|
||||
branchSession.getBranchId(), branchStatus);
|
||||
return CONTINUE;
|
||||
} else {
|
||||
LOGGER.error(
|
||||
"Committing global transaction[{}] failed, caused by branch transaction[{}] commit failed, will retry later.", globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
StackTraceLogger.error(LOGGER, ex, "Committing branch transaction exception: {}",
|
||||
new String[] {branchSession.toString()});
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryCommit();
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
}
|
||||
return CONTINUE;
|
||||
});
|
||||
// Return if the result is not null
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
//If has branch and not all remaining branches can be committed asynchronously,
|
||||
//do print log and return false
|
||||
if (globalSession.hasBranch() && !globalSession.canBeCommittedAsync()) {
|
||||
LOGGER.info("Committing global transaction is NOT done, xid = {}.", globalSession.getXid());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if it succeeds and there is no branch, retrying=true is the asynchronous state when retrying. EndCommitted is
|
||||
// executed to improve concurrency performance, and the global transaction ends..
|
||||
if (success && globalSession.getBranchSessions().isEmpty()) {
|
||||
if (!retrying) {
|
||||
//contains not AT branch
|
||||
globalSession.setStatus(GlobalStatus.Committed);
|
||||
}
|
||||
SessionHelper.endCommitted(globalSession, retrying);
|
||||
LOGGER.info("Committing global transaction is successfully done, xid = {}.", globalSession.getXid());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
boolean rollbackSuccess = doGlobalRollback(globalSession, false);
|
||||
return rollbackSuccess ? GlobalStatus.Rollbacked : globalSession.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus rollback(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
}
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
// just lock changeStatus
|
||||
boolean shouldRollBack = SessionHolder.lockAndExecute(globalSession, () -> {
|
||||
globalSession.close(); // Highlight: Firstly, close the session, then no more branch can be registered.
|
||||
if (globalSession.getStatus() == GlobalStatus.Begin) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Rollbacking);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (!shouldRollBack) {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
|
||||
boolean rollbackSuccess = doGlobalRollback(globalSession, false);
|
||||
return rollbackSuccess ? GlobalStatus.Rollbacked : globalSession.getStatus();
|
||||
}
|
||||
@Override
|
||||
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
boolean success = true;
|
||||
// start rollback event
|
||||
MetricsPublisher.postSessionDoingEvent(globalSession, retrying);
|
||||
|
||||
@Override
|
||||
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
boolean success = true;
|
||||
// start rollback event
|
||||
MetricsPublisher.postSessionDoingEvent(globalSession, retrying);
|
||||
if (globalSession.isSaga()) {
|
||||
success = getCore(BranchType.SAGA).doGlobalRollback(globalSession, retrying);
|
||||
}
|
||||
else {
|
||||
Boolean result = SessionHelper.forEach(globalSession.getReverseSortedBranches(), branchSession -> {
|
||||
BranchStatus currentBranchStatus = branchSession.getStatus();
|
||||
if (currentBranchStatus == BranchStatus.PhaseOne_Failed) {
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
}
|
||||
try {
|
||||
BranchStatus branchStatus = branchRollback(globalSession, branchSession);
|
||||
if (isXaerNotaTimeout(globalSession, branchStatus)) {
|
||||
LOGGER.info("Rollback branch XAER_NOTA retry timeout, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
branchStatus = BranchStatus.PhaseTwo_Rollbacked;
|
||||
}
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Rollbacked:
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
LOGGER.info("Rollback branch transaction successfully, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
return CONTINUE;
|
||||
case PhaseTwo_RollbackFailed_Unretryable:
|
||||
SessionHelper.endRollbackFailed(globalSession, retrying);
|
||||
LOGGER.info("Rollback branch transaction fail and stop retry, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
default:
|
||||
LOGGER.info("Rollback branch transaction fail and will retry, xid = {} branchId = {}",
|
||||
globalSession.getXid(), branchSession.getBranchId());
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
StackTraceLogger.error(LOGGER, ex,
|
||||
"Rollback branch transaction exception, xid = {} branchId = {} exception = {}",
|
||||
new String[] { globalSession.getXid(), String.valueOf(branchSession.getBranchId()),
|
||||
ex.getMessage() });
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
});
|
||||
// Return if the result is not null
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
if (globalSession.isSaga()) {
|
||||
success = getCore(BranchType.SAGA).doGlobalRollback(globalSession, retrying);
|
||||
} else {
|
||||
Boolean result = SessionHelper.forEach(globalSession.getReverseSortedBranches(), branchSession -> {
|
||||
BranchStatus currentBranchStatus = branchSession.getStatus();
|
||||
if (currentBranchStatus == BranchStatus.PhaseOne_Failed) {
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
return CONTINUE;
|
||||
}
|
||||
try {
|
||||
BranchStatus branchStatus = branchRollback(globalSession, branchSession);
|
||||
if (isXaerNotaTimeout(globalSession, branchStatus)) {
|
||||
LOGGER.info("Rollback branch XAER_NOTA retry timeout, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
|
||||
branchStatus = BranchStatus.PhaseTwo_Rollbacked;
|
||||
}
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Rollbacked:
|
||||
SessionHelper.removeBranch(globalSession, branchSession, !retrying);
|
||||
LOGGER.info("Rollback branch transaction successfully, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
|
||||
return CONTINUE;
|
||||
case PhaseTwo_RollbackFailed_Unretryable:
|
||||
SessionHelper.endRollbackFailed(globalSession, retrying);
|
||||
LOGGER.info("Rollback branch transaction fail and stop retry, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
|
||||
return false;
|
||||
default:
|
||||
LOGGER.info("Rollback branch transaction fail and will retry, xid = {} branchId = {}", globalSession.getXid(), branchSession.getBranchId());
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
StackTraceLogger.error(LOGGER, ex,
|
||||
"Rollback branch transaction exception, xid = {} branchId = {} exception = {}",
|
||||
new String[] {globalSession.getXid(), String.valueOf(branchSession.getBranchId()), ex.getMessage()});
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
});
|
||||
// Return if the result is not null
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// In db mode, lock and branch data residual problems may occur.
|
||||
// Therefore, execution needs to be delayed here and cannot be executed
|
||||
// synchronously.
|
||||
if (success) {
|
||||
SessionHelper.endRollbacked(globalSession, retrying);
|
||||
LOGGER.info("Rollback global transaction successfully, xid = {}.", globalSession.getXid());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
// In db mode, lock and branch data residual problems may occur.
|
||||
// Therefore, execution needs to be delayed here and cannot be executed synchronously.
|
||||
if (success) {
|
||||
SessionHelper.endRollbacked(globalSession, retrying);
|
||||
LOGGER.info("Rollback global transaction successfully, xid = {}.", globalSession.getXid());
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@Override
|
||||
public GlobalStatus getStatus(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid, false);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
}
|
||||
else {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus getStatus(String xid) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid, false);
|
||||
if (globalSession == null) {
|
||||
return GlobalStatus.Finished;
|
||||
} else {
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public GlobalStatus globalReport(String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return globalStatus;
|
||||
}
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
doGlobalReport(globalSession, xid, globalStatus);
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalStatus globalReport(String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
GlobalSession globalSession = SessionHolder.findGlobalSession(xid);
|
||||
if (globalSession == null) {
|
||||
return globalStatus;
|
||||
}
|
||||
globalSession.addSessionLifecycleListener(SessionHolder.getRootSessionManager());
|
||||
doGlobalReport(globalSession, xid, globalStatus);
|
||||
return globalSession.getStatus();
|
||||
}
|
||||
@Override
|
||||
public void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus globalStatus)
|
||||
throws TransactionException {
|
||||
if (globalSession.isSaga()) {
|
||||
getCore(BranchType.SAGA).doGlobalReport(globalSession, xid, globalStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
if (globalSession.isSaga()) {
|
||||
getCore(BranchType.SAGA).doGlobalReport(globalSession, xid, globalStatus);
|
||||
}
|
||||
}
|
||||
private boolean isXaerNotaTimeout(GlobalSession globalSession, BranchStatus branchStatus) {
|
||||
if (BranchStatus.PhaseTwo_CommitFailed_XAER_NOTA_Retryable.equals(branchStatus)
|
||||
|| BranchStatus.PhaseTwo_RollbackFailed_XAER_NOTA_Retryable.equals(branchStatus)) {
|
||||
return System.currentTimeMillis() > globalSession.getBeginTime() + globalSession.getTimeout()
|
||||
+ Math.max(RETRY_XAER_NOTA_TIMEOUT, globalSession.getTimeout());
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isXaerNotaTimeout(GlobalSession globalSession, BranchStatus branchStatus) {
|
||||
if (BranchStatus.PhaseTwo_CommitFailed_XAER_NOTA_Retryable.equals(branchStatus) ||
|
||||
BranchStatus.PhaseTwo_RollbackFailed_XAER_NOTA_Retryable.equals(branchStatus)) {
|
||||
return System.currentTimeMillis() > globalSession.getBeginTime() + globalSession.getTimeout() +
|
||||
Math.max(RETRY_XAER_NOTA_TIMEOUT, globalSession.getTimeout());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-21
@@ -28,27 +28,24 @@ import io.seata.server.session.GlobalSession;
|
||||
*/
|
||||
public interface TransactionCoordinatorOutbound {
|
||||
|
||||
/**
|
||||
* Commit a branch transaction.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @return Status of the branch after committing.
|
||||
* @throws TransactionException Any exception that fails this will be wrapped with TransactionException and thrown
|
||||
* out.
|
||||
*/
|
||||
BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Rollback a branch transaction.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @return Status of the branch after rollbacking.
|
||||
* @throws TransactionException Any exception that fails this will be wrapped with TransactionException and thrown
|
||||
* out.
|
||||
*/
|
||||
BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
/**
|
||||
* Commit a branch transaction.
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @return Status of the branch after committing.
|
||||
* @throws TransactionException Any exception that fails this will be wrapped with
|
||||
* TransactionException and thrown out.
|
||||
*/
|
||||
BranchStatus branchCommit(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Rollback a branch transaction.
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @return Status of the branch after rollbacking.
|
||||
* @throws TransactionException Any exception that fails this will be wrapped with
|
||||
* TransactionException and thrown out.
|
||||
*/
|
||||
BranchStatus branchRollback(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
|
||||
}
|
||||
+65
-65
@@ -26,78 +26,78 @@ import static io.seata.core.constants.ConfigurationKeys.ENV_SEATA_PORT_KEY;
|
||||
*/
|
||||
public class ContainerHelper {
|
||||
|
||||
private static final String C_GROUP_PATH = "/proc/1/cgroup";
|
||||
private static final String DOCKER_PATH = "/docker";
|
||||
private static final String KUBEPODS_PATH = "/kubepods";
|
||||
private static final String C_GROUP_PATH = "/proc/1/cgroup";
|
||||
|
||||
private static final String ENV_SYSTEM_KEY = "SEATA_ENV";
|
||||
private static final String ENV_SEATA_IP_KEY = "SEATA_IP";
|
||||
private static final String ENV_SERVER_NODE_KEY = "SERVER_NODE";
|
||||
private static final String ENV_STORE_MODE_KEY = "STORE_MODE";
|
||||
private static final String ENV_LOCK_STORE_MODE_KEY = "LOCK_STORE_MODE";
|
||||
private static final String ENV_SESSION_STORE_MODE_KEY = "SESSION_STORE_MODE";
|
||||
private static final String DOCKER_PATH = "/docker";
|
||||
|
||||
/**
|
||||
* Gets env from container.
|
||||
*
|
||||
* @return the env
|
||||
*/
|
||||
public static String getEnv() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SYSTEM_KEY));
|
||||
}
|
||||
private static final String KUBEPODS_PATH = "/kubepods";
|
||||
|
||||
/**
|
||||
* Gets host from container.
|
||||
*
|
||||
* @return the env
|
||||
*/
|
||||
public static String getHost() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SEATA_IP_KEY));
|
||||
}
|
||||
private static final String ENV_SYSTEM_KEY = "SEATA_ENV";
|
||||
|
||||
/**
|
||||
* Gets port from container.
|
||||
*
|
||||
* @return the env
|
||||
*/
|
||||
public static int getPort() {
|
||||
return NumberUtils.toInt(System.getenv(ENV_SEATA_PORT_KEY), 0);
|
||||
}
|
||||
private static final String ENV_SEATA_IP_KEY = "SEATA_IP";
|
||||
|
||||
/**
|
||||
* Gets server node from container.
|
||||
*
|
||||
* @return the env
|
||||
*/
|
||||
public static Long getServerNode() {
|
||||
return NumberUtils.toLong(System.getenv(ENV_SERVER_NODE_KEY));
|
||||
}
|
||||
private static final String ENV_SERVER_NODE_KEY = "SERVER_NODE";
|
||||
|
||||
/**
|
||||
* Gets store mode from container.
|
||||
*
|
||||
* @return the env
|
||||
*/
|
||||
public static String getStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_STORE_MODE_KEY));
|
||||
}
|
||||
private static final String ENV_STORE_MODE_KEY = "STORE_MODE";
|
||||
|
||||
/**
|
||||
* Gets session store mode from container.
|
||||
*
|
||||
* @return the env
|
||||
*/
|
||||
public static String getSessionStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SESSION_STORE_MODE_KEY));
|
||||
}
|
||||
private static final String ENV_LOCK_STORE_MODE_KEY = "LOCK_STORE_MODE";
|
||||
|
||||
/**
|
||||
* Gets lock store mode from container.
|
||||
*
|
||||
* @return the env
|
||||
*/
|
||||
public static String getLockStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_LOCK_STORE_MODE_KEY));
|
||||
}
|
||||
private static final String ENV_SESSION_STORE_MODE_KEY = "SESSION_STORE_MODE";
|
||||
|
||||
/**
|
||||
* Gets env from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getEnv() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SYSTEM_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets host from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getHost() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SEATA_IP_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets port from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static int getPort() {
|
||||
return NumberUtils.toInt(System.getenv(ENV_SEATA_PORT_KEY), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets server node from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static Long getServerNode() {
|
||||
return NumberUtils.toLong(System.getenv(ENV_SERVER_NODE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets store mode from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_STORE_MODE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets session store mode from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getSessionStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_SESSION_STORE_MODE_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock store mode from container.
|
||||
* @return the env
|
||||
*/
|
||||
public static String getLockStoreMode() {
|
||||
return StringUtils.trimToNull(System.getenv(ENV_LOCK_STORE_MODE_KEY));
|
||||
}
|
||||
|
||||
}
|
||||
+93
-89
@@ -31,100 +31,104 @@ import java.util.Properties;
|
||||
*/
|
||||
public class PortHelper {
|
||||
|
||||
public static int getPortFromEnvOrStartup(String[] args) {
|
||||
int port = 0;
|
||||
if (args != null && args.length >= 2) {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
if ("-p".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
port = NumberUtils.toInt(args[i + 1], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (port == 0) {
|
||||
port = ContainerHelper.getPort();
|
||||
}
|
||||
return port;
|
||||
}
|
||||
public static int getPortFromEnvOrStartup(String[] args) {
|
||||
int port = 0;
|
||||
if (args != null && args.length >= 2) {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
if ("-p".equalsIgnoreCase(args[i]) && i < args.length - 1) {
|
||||
port = NumberUtils.toInt(args[i + 1], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (port == 0) {
|
||||
port = ContainerHelper.getPort();
|
||||
}
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* get config from configFile
|
||||
* -Dspring.config.location > classpath:application.properties > classpath:application.yml
|
||||
*
|
||||
* @return the port
|
||||
* @throws IOException the io exception
|
||||
*/
|
||||
public static int getPortFromConfigFile() throws IOException {
|
||||
/**
|
||||
* get config from configFile -Dspring.config.location >
|
||||
* classpath:application.properties > classpath:application.yml
|
||||
* @return the port
|
||||
* @throws IOException the io exception
|
||||
*/
|
||||
public static int getPortFromConfigFile() throws IOException {
|
||||
|
||||
int port = 8080;
|
||||
File configFile = null;
|
||||
File startupConfigFile = getConfigFromStartup();
|
||||
if (null != startupConfigFile) {
|
||||
configFile = startupConfigFile;
|
||||
} else {
|
||||
try {
|
||||
File propertiesFile = ResourceUtils.getFile("classpath:application.properties");
|
||||
configFile = propertiesFile;
|
||||
} catch (FileNotFoundException exx) {
|
||||
File ymlFile = ResourceUtils.getFile("classpath:application.yml");
|
||||
configFile = ymlFile;
|
||||
}
|
||||
}
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(configFile);
|
||||
String fileName = configFile.getName();
|
||||
String portNum = null;
|
||||
if (fileName.endsWith("yml")) {
|
||||
Map<String, Object> yamlMap = new Yaml().load(inputStream);
|
||||
Map<String, Object> configMap = MapUtil.getFlattenedMap(yamlMap);
|
||||
if (CollectionUtils.isNotEmpty(configMap)) {
|
||||
Object serverPort = configMap.get("server.port");
|
||||
if (null != serverPort) {
|
||||
portNum = serverPort.toString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Properties properties = new Properties();
|
||||
properties.load(inputStream);
|
||||
portNum = properties.getProperty("server.port");
|
||||
}
|
||||
if (null != portNum) {
|
||||
try {
|
||||
port = Integer.parseInt(portNum);
|
||||
} catch (NumberFormatException exx) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (null != inputStream) {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
return port;
|
||||
int port = 8080;
|
||||
File configFile = null;
|
||||
File startupConfigFile = getConfigFromStartup();
|
||||
if (null != startupConfigFile) {
|
||||
configFile = startupConfigFile;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
File propertiesFile = ResourceUtils.getFile("classpath:application.properties");
|
||||
configFile = propertiesFile;
|
||||
}
|
||||
catch (FileNotFoundException exx) {
|
||||
File ymlFile = ResourceUtils.getFile("classpath:application.yml");
|
||||
configFile = ymlFile;
|
||||
}
|
||||
}
|
||||
InputStream inputStream = null;
|
||||
try {
|
||||
inputStream = new FileInputStream(configFile);
|
||||
String fileName = configFile.getName();
|
||||
String portNum = null;
|
||||
if (fileName.endsWith("yml")) {
|
||||
Map<String, Object> yamlMap = new Yaml().load(inputStream);
|
||||
Map<String, Object> configMap = MapUtil.getFlattenedMap(yamlMap);
|
||||
if (CollectionUtils.isNotEmpty(configMap)) {
|
||||
Object serverPort = configMap.get("server.port");
|
||||
if (null != serverPort) {
|
||||
portNum = serverPort.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Properties properties = new Properties();
|
||||
properties.load(inputStream);
|
||||
portNum = properties.getProperty("server.port");
|
||||
}
|
||||
if (null != portNum) {
|
||||
try {
|
||||
port = Integer.parseInt(portNum);
|
||||
}
|
||||
catch (NumberFormatException exx) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (null != inputStream) {
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
||||
return port;
|
||||
|
||||
}
|
||||
private static File getConfigFromStartup() {
|
||||
}
|
||||
|
||||
String configLocation = System.getProperty("spring.config.location");
|
||||
if (StringUtils.isNotBlank(configLocation)) {
|
||||
try {
|
||||
File configFile = ResourceUtils.getFile(configLocation);
|
||||
if (!configFile.isFile()) {
|
||||
return null;
|
||||
}
|
||||
String fileName = configFile.getName();
|
||||
if (!(fileName.endsWith("yml") || fileName.endsWith("properties"))) {
|
||||
return null;
|
||||
}
|
||||
return configFile;
|
||||
} catch (FileNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
private static File getConfigFromStartup() {
|
||||
|
||||
}
|
||||
String configLocation = System.getProperty("spring.config.location");
|
||||
if (StringUtils.isNotBlank(configLocation)) {
|
||||
try {
|
||||
File configFile = ResourceUtils.getFile(configLocation);
|
||||
if (!configFile.isFile()) {
|
||||
return null;
|
||||
}
|
||||
String fileName = configFile.getName();
|
||||
if (!(fileName.endsWith("yml") || fileName.endsWith("properties"))) {
|
||||
return null;
|
||||
}
|
||||
return configFile;
|
||||
}
|
||||
catch (FileNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+10
-6
@@ -24,11 +24,15 @@ import io.seata.core.event.GuavaEventBus;
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class EventBusManager {
|
||||
private static class SingletonHolder {
|
||||
private static EventBus INSTANCE = new GuavaEventBus("tc",true);
|
||||
}
|
||||
|
||||
public static EventBus get() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
private static class SingletonHolder {
|
||||
|
||||
private static EventBus INSTANCE = new GuavaEventBus("tc", true);
|
||||
|
||||
}
|
||||
|
||||
public static EventBus get() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
}
|
||||
+141
-143
@@ -37,162 +37,160 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class AbstractLockManager implements LockManager {
|
||||
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractLockManager.class);
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractLockManager.class);
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(BranchSession branchSession) throws TransactionException {
|
||||
return acquireLock(branchSession, true, false);
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(BranchSession branchSession) throws TransactionException {
|
||||
return acquireLock(branchSession, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(BranchSession branchSession, boolean autoCommit, boolean skipCheckLock) throws TransactionException {
|
||||
if (branchSession == null) {
|
||||
throw new IllegalArgumentException("branchSession can't be null for memory/file locker.");
|
||||
}
|
||||
String lockKey = branchSession.getLockKey();
|
||||
if (StringUtils.isNullOrEmpty(lockKey)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
// get locks of branch
|
||||
List<RowLock> locks = collectRowLocks(branchSession);
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
return getLocker(branchSession).acquireLock(locks, autoCommit, skipCheckLock);
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(BranchSession branchSession, boolean autoCommit, boolean skipCheckLock)
|
||||
throws TransactionException {
|
||||
if (branchSession == null) {
|
||||
throw new IllegalArgumentException("branchSession can't be null for memory/file locker.");
|
||||
}
|
||||
String lockKey = branchSession.getLockKey();
|
||||
if (StringUtils.isNullOrEmpty(lockKey)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
// get locks of branch
|
||||
List<RowLock> locks = collectRowLocks(branchSession);
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
return getLocker(branchSession).acquireLock(locks, autoCommit, skipCheckLock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(BranchSession branchSession) throws TransactionException {
|
||||
if (branchSession == null) {
|
||||
throw new IllegalArgumentException("branchSession can't be null for memory/file locker.");
|
||||
}
|
||||
List<RowLock> locks = collectRowLocks(branchSession);
|
||||
try {
|
||||
return getLocker(branchSession).releaseLock(locks);
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("unLock error, branchSession:{}", branchSession, t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(BranchSession branchSession) throws TransactionException {
|
||||
if (branchSession == null) {
|
||||
throw new IllegalArgumentException("branchSession can't be null for memory/file locker.");
|
||||
}
|
||||
List<RowLock> locks = collectRowLocks(branchSession);
|
||||
try {
|
||||
return getLocker(branchSession).releaseLock(locks);
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("unLock error, branchSession:{}", branchSession, t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLockable(String xid, String resourceId, String lockKey) throws TransactionException {
|
||||
if (StringUtils.isBlank(lockKey)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
List<RowLock> locks = collectRowLocks(lockKey, resourceId, xid);
|
||||
try {
|
||||
return getLocker().isLockable(locks);
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("isLockable error, xid:{} resourceId:{}, lockKey:{}", xid, resourceId, lockKey, t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean isLockable(String xid, String resourceId, String lockKey) throws TransactionException {
|
||||
if (StringUtils.isBlank(lockKey)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
List<RowLock> locks = collectRowLocks(lockKey, resourceId, xid);
|
||||
try {
|
||||
return getLocker().isLockable(locks);
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("isLockable error, xid:{} resourceId:{}, lockKey:{}", xid, resourceId, lockKey, t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanAllLocks() throws TransactionException {
|
||||
getLocker().cleanAllLocks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanAllLocks() throws TransactionException {
|
||||
getLocker().cleanAllLocks();
|
||||
}
|
||||
/**
|
||||
* Gets locker.
|
||||
* @return the locker
|
||||
*/
|
||||
protected Locker getLocker() {
|
||||
return getLocker(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets locker.
|
||||
*
|
||||
* @return the locker
|
||||
*/
|
||||
protected Locker getLocker() {
|
||||
return getLocker(null);
|
||||
}
|
||||
/**
|
||||
* Gets locker.
|
||||
* @param branchSession the branch session
|
||||
* @return the locker
|
||||
*/
|
||||
protected abstract Locker getLocker(BranchSession branchSession);
|
||||
|
||||
/**
|
||||
* Gets locker.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @return the locker
|
||||
*/
|
||||
protected abstract Locker getLocker(BranchSession branchSession);
|
||||
@Override
|
||||
public List<RowLock> collectRowLocks(BranchSession branchSession) {
|
||||
if (branchSession == null || StringUtils.isBlank(branchSession.getLockKey())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RowLock> collectRowLocks(BranchSession branchSession) {
|
||||
if (branchSession == null || StringUtils.isBlank(branchSession.getLockKey())) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
String lockKey = branchSession.getLockKey();
|
||||
String resourceId = branchSession.getResourceId();
|
||||
String xid = branchSession.getXid();
|
||||
long transactionId = branchSession.getTransactionId();
|
||||
long branchId = branchSession.getBranchId();
|
||||
|
||||
String lockKey = branchSession.getLockKey();
|
||||
String resourceId = branchSession.getResourceId();
|
||||
String xid = branchSession.getXid();
|
||||
long transactionId = branchSession.getTransactionId();
|
||||
long branchId = branchSession.getBranchId();
|
||||
return collectRowLocks(lockKey, resourceId, xid, transactionId, branchId);
|
||||
}
|
||||
|
||||
return collectRowLocks(lockKey, resourceId, xid, transactionId, branchId);
|
||||
}
|
||||
/**
|
||||
* Collect row locks list.
|
||||
* @param lockKey the lock key
|
||||
* @param resourceId the resource id
|
||||
* @param xid the xid
|
||||
* @return the list
|
||||
*/
|
||||
protected List<RowLock> collectRowLocks(String lockKey, String resourceId, String xid) {
|
||||
return collectRowLocks(lockKey, resourceId, xid, XID.getTransactionId(xid), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collect row locks list.
|
||||
*
|
||||
* @param lockKey the lock key
|
||||
* @param resourceId the resource id
|
||||
* @param xid the xid
|
||||
* @return the list
|
||||
*/
|
||||
protected List<RowLock> collectRowLocks(String lockKey, String resourceId, String xid) {
|
||||
return collectRowLocks(lockKey, resourceId, xid, XID.getTransactionId(xid), null);
|
||||
}
|
||||
/**
|
||||
* Collect row locks list.
|
||||
* @param lockKey the lock key
|
||||
* @param resourceId the resource id
|
||||
* @param xid the xid
|
||||
* @param transactionId the transaction id
|
||||
* @param branchID the branch id
|
||||
* @return the list
|
||||
*/
|
||||
protected List<RowLock> collectRowLocks(String lockKey, String resourceId, String xid, Long transactionId,
|
||||
Long branchID) {
|
||||
List<RowLock> locks = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Collect row locks list.
|
||||
*
|
||||
* @param lockKey the lock key
|
||||
* @param resourceId the resource id
|
||||
* @param xid the xid
|
||||
* @param transactionId the transaction id
|
||||
* @param branchID the branch id
|
||||
* @return the list
|
||||
*/
|
||||
protected List<RowLock> collectRowLocks(String lockKey, String resourceId, String xid, Long transactionId,
|
||||
Long branchID) {
|
||||
List<RowLock> locks = new ArrayList<>();
|
||||
String[] tableGroupedLockKeys = lockKey.split(";");
|
||||
for (String tableGroupedLockKey : tableGroupedLockKeys) {
|
||||
int idx = tableGroupedLockKey.indexOf(":");
|
||||
if (idx < 0) {
|
||||
return locks;
|
||||
}
|
||||
String tableName = tableGroupedLockKey.substring(0, idx);
|
||||
String mergedPKs = tableGroupedLockKey.substring(idx + 1);
|
||||
if (StringUtils.isBlank(mergedPKs)) {
|
||||
return locks;
|
||||
}
|
||||
String[] pks = mergedPKs.split(",");
|
||||
if (pks == null || pks.length == 0) {
|
||||
return locks;
|
||||
}
|
||||
for (String pk : pks) {
|
||||
if (StringUtils.isNotBlank(pk)) {
|
||||
RowLock rowLock = new RowLock();
|
||||
rowLock.setXid(xid);
|
||||
rowLock.setTransactionId(transactionId);
|
||||
rowLock.setBranchId(branchID);
|
||||
rowLock.setTableName(tableName);
|
||||
rowLock.setPk(pk);
|
||||
rowLock.setResourceId(resourceId);
|
||||
locks.add(rowLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
return locks;
|
||||
}
|
||||
|
||||
String[] tableGroupedLockKeys = lockKey.split(";");
|
||||
for (String tableGroupedLockKey : tableGroupedLockKeys) {
|
||||
int idx = tableGroupedLockKey.indexOf(":");
|
||||
if (idx < 0) {
|
||||
return locks;
|
||||
}
|
||||
String tableName = tableGroupedLockKey.substring(0, idx);
|
||||
String mergedPKs = tableGroupedLockKey.substring(idx + 1);
|
||||
if (StringUtils.isBlank(mergedPKs)) {
|
||||
return locks;
|
||||
}
|
||||
String[] pks = mergedPKs.split(",");
|
||||
if (pks == null || pks.length == 0) {
|
||||
return locks;
|
||||
}
|
||||
for (String pk : pks) {
|
||||
if (StringUtils.isNotBlank(pk)) {
|
||||
RowLock rowLock = new RowLock();
|
||||
rowLock.setXid(xid);
|
||||
rowLock.setTransactionId(transactionId);
|
||||
rowLock.setBranchId(branchID);
|
||||
rowLock.setTableName(tableName);
|
||||
rowLock.setPk(pk);
|
||||
rowLock.setResourceId(resourceId);
|
||||
locks.add(rowLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
return locks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
this.getLocker().updateLockStatus(xid, lockStatus);
|
||||
}
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
this.getLocker().updateLockStatus(xid, lockStatus);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,77 +30,71 @@ import java.util.List;
|
||||
*/
|
||||
public interface LockManager {
|
||||
|
||||
/**
|
||||
* Acquire lock boolean.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean acquireLock(BranchSession branchSession) throws TransactionException;
|
||||
/**
|
||||
* Acquire lock boolean.
|
||||
* @param branchSession the branch session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean acquireLock(BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Acquire lock boolean.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @param autoCommit the auto commit
|
||||
* @param skipCheckLock whether skip check lock or not
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean acquireLock(BranchSession branchSession, boolean autoCommit, boolean skipCheckLock) throws TransactionException;
|
||||
/**
|
||||
* Acquire lock boolean.
|
||||
* @param branchSession the branch session
|
||||
* @param autoCommit the auto commit
|
||||
* @param skipCheckLock whether skip check lock or not
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean acquireLock(BranchSession branchSession, boolean autoCommit, boolean skipCheckLock)
|
||||
throws TransactionException;
|
||||
|
||||
/**
|
||||
* Un lock boolean.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean releaseLock(BranchSession branchSession) throws TransactionException;
|
||||
/**
|
||||
* Un lock boolean.
|
||||
* @param branchSession the branch session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean releaseLock(BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Un lock boolean.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException;
|
||||
/**
|
||||
* Un lock boolean.
|
||||
* @param globalSession the global session
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Is lockable boolean.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @param resourceId the resource id
|
||||
* @param lockKey the lock key
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean isLockable(String xid, String resourceId, String lockKey) throws TransactionException;
|
||||
/**
|
||||
* Is lockable boolean.
|
||||
* @param xid the xid
|
||||
* @param resourceId the resource id
|
||||
* @param lockKey the lock key
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean isLockable(String xid, String resourceId, String lockKey) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Clean all locks.
|
||||
*
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void cleanAllLocks() throws TransactionException;
|
||||
/**
|
||||
* Clean all locks.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void cleanAllLocks() throws TransactionException;
|
||||
|
||||
/**
|
||||
* Collect row locks list.`
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @return the list
|
||||
*/
|
||||
List<RowLock> collectRowLocks(BranchSession branchSession);
|
||||
/**
|
||||
* Collect row locks list.`
|
||||
* @param branchSession the branch session
|
||||
* @return the list
|
||||
*/
|
||||
List<RowLock> collectRowLocks(BranchSession branchSession);
|
||||
|
||||
/**
|
||||
* update lock status.
|
||||
* @param xid the xid
|
||||
* @param lockStatus the lock status
|
||||
* @throws TransactionException the transaction exception
|
||||
*
|
||||
*/
|
||||
void updateLockStatus(String xid, LockStatus lockStatus) throws TransactionException;
|
||||
/**
|
||||
* update lock status.
|
||||
* @param xid the xid
|
||||
* @param lockStatus the lock status
|
||||
* @throws TransactionException the transaction exception
|
||||
*
|
||||
*/
|
||||
void updateLockStatus(String xid, LockStatus lockStatus) throws TransactionException;
|
||||
|
||||
}
|
||||
+33
-34
@@ -28,43 +28,42 @@ import io.seata.server.store.StoreConfig.LockMode;
|
||||
*/
|
||||
public class LockerManagerFactory {
|
||||
|
||||
private static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
private static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
|
||||
/**
|
||||
* the lock manager
|
||||
*/
|
||||
private static volatile LockManager LOCK_MANAGER;
|
||||
/**
|
||||
* the lock manager
|
||||
*/
|
||||
private static volatile LockManager LOCK_MANAGER;
|
||||
|
||||
/**
|
||||
* Get lock manager.
|
||||
*
|
||||
* @return the lock manager
|
||||
*/
|
||||
public static LockManager getLockManager() {
|
||||
if (LOCK_MANAGER == null) {
|
||||
init();
|
||||
}
|
||||
return LOCK_MANAGER;
|
||||
}
|
||||
/**
|
||||
* Get lock manager.
|
||||
* @return the lock manager
|
||||
*/
|
||||
public static LockManager getLockManager() {
|
||||
if (LOCK_MANAGER == null) {
|
||||
init();
|
||||
}
|
||||
return LOCK_MANAGER;
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
init(null);
|
||||
}
|
||||
public static void init() {
|
||||
init(null);
|
||||
}
|
||||
|
||||
public static void init(LockMode lockMode) {
|
||||
if (LOCK_MANAGER == null) {
|
||||
synchronized (LockerManagerFactory.class) {
|
||||
if (LOCK_MANAGER == null) {
|
||||
if (null == lockMode) {
|
||||
lockMode = StoreConfig.getLockMode();
|
||||
}
|
||||
//if not exist the lock mode, throw exception
|
||||
if (null != StoreConfig.StoreMode.get(lockMode.name())) {
|
||||
LOCK_MANAGER = EnhancedServiceLoader.load(LockManager.class, lockMode.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void init(LockMode lockMode) {
|
||||
if (LOCK_MANAGER == null) {
|
||||
synchronized (LockerManagerFactory.class) {
|
||||
if (LOCK_MANAGER == null) {
|
||||
if (null == lockMode) {
|
||||
lockMode = StoreConfig.getLockMode();
|
||||
}
|
||||
// if not exist the lock mode, throw exception
|
||||
if (null != StoreConfig.StoreMode.get(lockMode.name())) {
|
||||
LOCK_MANAGER = EnhancedServiceLoader.load(LockManager.class, lockMode.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+37
-35
@@ -24,46 +24,48 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Distributed locker factory
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
public class DistributedLockerFactory {
|
||||
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedLockerFactory.class);
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedLockerFactory.class);
|
||||
|
||||
private static volatile DistributedLocker DISTRIBUTED_LOCKER = null;
|
||||
private static volatile DistributedLocker DISTRIBUTED_LOCKER = null;
|
||||
|
||||
/**
|
||||
* Get the distributed locker by lockerType
|
||||
*
|
||||
* @param lockerType the locker type
|
||||
* @return the distributed locker
|
||||
*/
|
||||
public static DistributedLocker getDistributedLocker(String lockerType) {
|
||||
if (DISTRIBUTED_LOCKER == null) {
|
||||
synchronized (DistributedLocker.class) {
|
||||
if (DISTRIBUTED_LOCKER == null) {
|
||||
DistributedLocker distributedLocker = null;
|
||||
try {
|
||||
if (!"file".equals(lockerType)) {
|
||||
distributedLocker = EnhancedServiceLoader.load(DistributedLocker.class, lockerType);
|
||||
}
|
||||
} catch (EnhancedServiceNotFoundException ex) {
|
||||
LOGGER.error("Get distributed locker failed: {}", ex.getMessage(), ex);
|
||||
}
|
||||
if (distributedLocker == null) {
|
||||
distributedLocker = new DefaultDistributedLocker();
|
||||
}
|
||||
DISTRIBUTED_LOCKER = distributedLocker;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DISTRIBUTED_LOCKER;
|
||||
}
|
||||
/**
|
||||
* Get the distributed locker by lockerType
|
||||
* @param lockerType the locker type
|
||||
* @return the distributed locker
|
||||
*/
|
||||
public static DistributedLocker getDistributedLocker(String lockerType) {
|
||||
if (DISTRIBUTED_LOCKER == null) {
|
||||
synchronized (DistributedLocker.class) {
|
||||
if (DISTRIBUTED_LOCKER == null) {
|
||||
DistributedLocker distributedLocker = null;
|
||||
try {
|
||||
if (!"file".equals(lockerType)) {
|
||||
distributedLocker = EnhancedServiceLoader.load(DistributedLocker.class, lockerType);
|
||||
}
|
||||
}
|
||||
catch (EnhancedServiceNotFoundException ex) {
|
||||
LOGGER.error("Get distributed locker failed: {}", ex.getMessage(), ex);
|
||||
}
|
||||
if (distributedLocker == null) {
|
||||
distributedLocker = new DefaultDistributedLocker();
|
||||
}
|
||||
DISTRIBUTED_LOCKER = distributedLocker;
|
||||
}
|
||||
}
|
||||
}
|
||||
return DISTRIBUTED_LOCKER;
|
||||
}
|
||||
|
||||
public static void cleanLocker() {
|
||||
DISTRIBUTED_LOCKER = null;
|
||||
}
|
||||
|
||||
public static void cleanLocker() {
|
||||
DISTRIBUTED_LOCKER = null;
|
||||
}
|
||||
}
|
||||
+34
-33
@@ -29,47 +29,48 @@ import io.seata.core.constants.ConfigurationKeys;
|
||||
*/
|
||||
public class SystemPropertyLoggerContextListener extends ContextAwareBase implements LoggerContextListener, LifeCycle {
|
||||
|
||||
private boolean started = false;
|
||||
private boolean started = false;
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (started) {
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
public void start() {
|
||||
if (started) {
|
||||
return;
|
||||
}
|
||||
|
||||
Context context = getContext();
|
||||
context.putProperty("RPC_PORT", System.getProperty(ConfigurationKeys.SERVER_SERVICE_PORT_CAMEL));
|
||||
Context context = getContext();
|
||||
context.putProperty("RPC_PORT", System.getProperty(ConfigurationKeys.SERVER_SERVICE_PORT_CAMEL));
|
||||
|
||||
started = true;
|
||||
}
|
||||
started = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
return started;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResetResistant() {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean isResetResistant() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(LoggerContext context) {
|
||||
}
|
||||
@Override
|
||||
public void onStart(LoggerContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReset(LoggerContext context) {
|
||||
}
|
||||
@Override
|
||||
public void onReset(LoggerContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(LoggerContext context) {
|
||||
}
|
||||
@Override
|
||||
public void onStop(LoggerContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLevelChange(Logger logger, Level level) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLevelChange(Logger logger, Level level) {
|
||||
}
|
||||
}
|
||||
+8
-7
@@ -21,15 +21,16 @@ import ch.qos.logback.core.CoreConstants;
|
||||
|
||||
/**
|
||||
* {@link ExtendedThrowableProxyConverter} that adds some additional whitespace around the
|
||||
* stack trace.
|
||||
* Copied from spring-boot-xxx.jar by wang.liang
|
||||
* stack trace. Copied from spring-boot-xxx.jar by wang.liang
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class ExtendedWhitespaceThrowableProxyConverter extends ExtendedThrowableProxyConverter {
|
||||
|
||||
@Override
|
||||
protected String throwableProxyToString(IThrowableProxy tp) {
|
||||
return "==>" + CoreConstants.LINE_SEPARATOR + super.throwableProxyToString(tp)
|
||||
+ "<==" + CoreConstants.LINE_SEPARATOR + CoreConstants.LINE_SEPARATOR;
|
||||
}
|
||||
@Override
|
||||
protected String throwableProxyToString(IThrowableProxy tp) {
|
||||
return "==>" + CoreConstants.LINE_SEPARATOR + super.throwableProxyToString(tp) + "<=="
|
||||
+ CoreConstants.LINE_SEPARATOR + CoreConstants.LINE_SEPARATOR;
|
||||
}
|
||||
|
||||
}
|
||||
+13
-13
@@ -29,17 +29,17 @@ import java.util.ArrayList;
|
||||
*/
|
||||
public class EnhancedLogstashEncoder extends LogstashEncoder {
|
||||
|
||||
/**
|
||||
* set exclude provider
|
||||
*
|
||||
* @param excludedProviderClassName the excluded provider class name
|
||||
*/
|
||||
public void setExcludeProvider(String excludedProviderClassName) {
|
||||
JsonProviders<?> providers = getFormatter().getProviders();
|
||||
for (JsonProvider<?> provider : new ArrayList<>(providers.getProviders())) {
|
||||
if (provider.getClass().getName().equals(excludedProviderClassName)) {
|
||||
providers.removeProvider((JsonProvider) provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* set exclude provider
|
||||
* @param excludedProviderClassName the excluded provider class name
|
||||
*/
|
||||
public void setExcludeProvider(String excludedProviderClassName) {
|
||||
JsonProviders<?> providers = getFormatter().getProviders();
|
||||
for (JsonProvider<?> provider : new ArrayList<>(providers.getProviders())) {
|
||||
if (provider.getClass().getName().equals(excludedProviderClassName)) {
|
||||
providers.removeProvider((JsonProvider) provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+59
-64
@@ -24,85 +24,80 @@ import io.seata.metrics.IdConstants;
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public interface MeterIdConstants {
|
||||
Id COUNTER_ACTIVE = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ACTIVE);
|
||||
|
||||
Id COUNTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
Id COUNTER_ACTIVE = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ACTIVE);
|
||||
|
||||
Id COUNTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
Id COUNTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
|
||||
Id COUNTER_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
Id COUNTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
|
||||
Id COUNTER_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
Id COUNTER_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
|
||||
Id COUNTER_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_COUNTER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
|
||||
Id SUMMARY_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
Id SUMMARY_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
|
||||
Id SUMMARY_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
Id SUMMARY_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
|
||||
Id SUMMARY_FAILED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_FAILED);
|
||||
Id SUMMARY_FAILED = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_FAILED);
|
||||
|
||||
Id SUMMARY_TWO_PHASE_TIMEOUT = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_TWO_PHASE_TIMEOUT);
|
||||
Id SUMMARY_TWO_PHASE_TIMEOUT = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_TWO_PHASE_TIMEOUT);
|
||||
|
||||
Id SUMMARY_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
Id SUMMARY_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
|
||||
Id SUMMARY_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
Id SUMMARY_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_SUMMARY)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
|
||||
Id TIMER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
Id TIMER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_COMMITTED);
|
||||
|
||||
Id TIMER_ROLLBACK = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
Id TIMER_ROLLBACK = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_ROLLBACKED);
|
||||
|
||||
Id TIMER_FAILED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_FAILED);
|
||||
Id TIMER_FAILED = new Id(IdConstants.SEATA_TRANSACTION).withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_FAILED);
|
||||
|
||||
Id TIMER_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
Id TIMER_AFTER_ROLLBACKED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY);
|
||||
|
||||
Id TIMER_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
Id TIMER_AFTER_COMMITTED = new Id(IdConstants.SEATA_TRANSACTION)
|
||||
.withTag(IdConstants.ROLE_KEY, IdConstants.ROLE_VALUE_TC)
|
||||
.withTag(IdConstants.METER_KEY, IdConstants.METER_VALUE_TIMER)
|
||||
.withTag(IdConstants.STATUS_KEY, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY);
|
||||
|
||||
}
|
||||
+30
-25
@@ -33,33 +33,38 @@ import static io.seata.common.DefaultValues.DEFAULT_METRICS_ENABLED;
|
||||
* @author zhengyangyong
|
||||
*/
|
||||
public class MetricsManager {
|
||||
private static class SingletonHolder {
|
||||
private static MetricsManager INSTANCE = new MetricsManager();
|
||||
}
|
||||
|
||||
public static final MetricsManager get() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
private static class SingletonHolder {
|
||||
|
||||
private Registry registry;
|
||||
private static MetricsManager INSTANCE = new MetricsManager();
|
||||
|
||||
public Registry getRegistry() {
|
||||
return registry;
|
||||
}
|
||||
}
|
||||
|
||||
public static final MetricsManager get() {
|
||||
return SingletonHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private Registry registry;
|
||||
|
||||
public Registry getRegistry() {
|
||||
return registry;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
boolean enabled = ConfigurationFactory.getInstance().getBoolean(
|
||||
ConfigurationKeys.METRICS_PREFIX + ConfigurationKeys.METRICS_ENABLED, DEFAULT_METRICS_ENABLED);
|
||||
if (enabled) {
|
||||
registry = RegistryFactory.getInstance();
|
||||
if (registry != null) {
|
||||
List<Exporter> exporters = ExporterFactory.getInstanceList();
|
||||
// only at least one metrics exporter implement had imported in pom then
|
||||
// need register MetricsSubscriber
|
||||
if (exporters.size() != 0) {
|
||||
exporters.forEach(exporter -> exporter.setRegistry(registry));
|
||||
EventBusManager.get().register(new MetricsSubscriber(registry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void init() {
|
||||
boolean enabled = ConfigurationFactory.getInstance().getBoolean(
|
||||
ConfigurationKeys.METRICS_PREFIX + ConfigurationKeys.METRICS_ENABLED, DEFAULT_METRICS_ENABLED);
|
||||
if (enabled) {
|
||||
registry = RegistryFactory.getInstance();
|
||||
if (registry != null) {
|
||||
List<Exporter> exporters = ExporterFactory.getInstanceList();
|
||||
//only at least one metrics exporter implement had imported in pom then need register MetricsSubscriber
|
||||
if (exporters.size() != 0) {
|
||||
exporters.forEach(exporter -> exporter.setRegistry(registry));
|
||||
EventBusManager.get().register(new MetricsSubscriber(registry));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+60
-61
@@ -28,70 +28,69 @@ import io.seata.server.session.GlobalSession;
|
||||
*/
|
||||
public class MetricsPublisher {
|
||||
|
||||
private static final EventBus EVENT_BUS = EventBusManager.get();
|
||||
private static final EventBus EVENT_BUS = EventBusManager.get();
|
||||
|
||||
/**
|
||||
* post end event
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
postSessionDoneEvent(globalSession, globalSession.getStatus(), retryGlobal, retryBranch);
|
||||
}
|
||||
/**
|
||||
* post end event
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
postSessionDoneEvent(globalSession, globalSession.getStatus(), retryGlobal, retryBranch);
|
||||
}
|
||||
|
||||
/**
|
||||
* post end event (force specified state)
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param status the global status
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, GlobalStatus status, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
postSessionDoneEvent(globalSession, status.name(), retryGlobal, globalSession.getBeginTime(), retryBranch);
|
||||
}
|
||||
/**
|
||||
* post end event (force specified state)
|
||||
* @param globalSession the global session
|
||||
* @param status the global status
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, GlobalStatus status, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
postSessionDoneEvent(globalSession, status.name(), retryGlobal, globalSession.getBeginTime(), retryBranch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post session done event.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param status the status
|
||||
* @param retryGlobal the retry global
|
||||
* @param beginTime the begin time
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, String status, boolean retryGlobal, long beginTime, boolean retryBranch) {
|
||||
EVENT_BUS.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
|
||||
globalSession.getTransactionName(), globalSession.getApplicationId(),
|
||||
globalSession.getTransactionServiceGroup(), beginTime, System.currentTimeMillis(), status, retryGlobal, retryBranch));
|
||||
}
|
||||
/**
|
||||
* Post session done event.
|
||||
* @param globalSession the global session
|
||||
* @param status the status
|
||||
* @param retryGlobal the retry global
|
||||
* @param beginTime the begin time
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoneEvent(final GlobalSession globalSession, String status, boolean retryGlobal,
|
||||
long beginTime, boolean retryBranch) {
|
||||
EVENT_BUS.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
|
||||
globalSession.getTransactionName(), globalSession.getApplicationId(),
|
||||
globalSession.getTransactionServiceGroup(), beginTime, System.currentTimeMillis(), status, retryGlobal,
|
||||
retryBranch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Post session doing event.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
*/
|
||||
public static void postSessionDoingEvent(final GlobalSession globalSession, boolean retryGlobal) {
|
||||
postSessionDoingEvent(globalSession, globalSession.getStatus().name(), retryGlobal, false);
|
||||
}
|
||||
/**
|
||||
* Post session doing event.
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
*/
|
||||
public static void postSessionDoingEvent(final GlobalSession globalSession, boolean retryGlobal) {
|
||||
postSessionDoingEvent(globalSession, globalSession.getStatus().name(), retryGlobal, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Post session doing event.
|
||||
* @param globalSession the global session
|
||||
* @param status the status
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoingEvent(final GlobalSession globalSession, String status, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
EVENT_BUS.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
|
||||
globalSession.getTransactionName(), globalSession.getApplicationId(),
|
||||
globalSession.getTransactionServiceGroup(), globalSession.getBeginTime(), null, status, retryGlobal,
|
||||
retryBranch));
|
||||
}
|
||||
|
||||
/**
|
||||
* Post session doing event.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param status the status
|
||||
* @param retryGlobal the retry global
|
||||
* @param retryBranch the retry branch
|
||||
*/
|
||||
public static void postSessionDoingEvent(final GlobalSession globalSession, String status, boolean retryGlobal,
|
||||
boolean retryBranch) {
|
||||
EVENT_BUS.post(new GlobalTransactionEvent(globalSession.getTransactionId(), GlobalTransactionEvent.ROLE_TC,
|
||||
globalSession.getTransactionName(), globalSession.getApplicationId(),
|
||||
globalSession.getTransactionServiceGroup(), globalSession.getBeginTime(), null, status, retryGlobal, retryBranch));
|
||||
}
|
||||
}
|
||||
+132
-150
@@ -37,178 +37,160 @@ import static io.seata.metrics.IdConstants.*;
|
||||
*/
|
||||
public class MetricsSubscriber {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MetricsSubscriber.class);
|
||||
private final Registry registry;
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(MetricsSubscriber.class);
|
||||
|
||||
private final Map<String, Consumer<GlobalTransactionEvent>> consumers;
|
||||
private final Registry registry;
|
||||
|
||||
public MetricsSubscriber(Registry registry) {
|
||||
this.registry = registry;
|
||||
consumers = new HashMap<>();
|
||||
consumers.put(GlobalStatus.Begin.name(), this::processGlobalStatusBegin);
|
||||
consumers.put(GlobalStatus.Committed.name(), this::processGlobalStatusCommitted);
|
||||
consumers.put(GlobalStatus.Rollbacked.name(), this::processGlobalStatusRollbacked);
|
||||
private final Map<String, Consumer<GlobalTransactionEvent>> consumers;
|
||||
|
||||
consumers.put(GlobalStatus.CommitFailed.name(), this::processGlobalStatusCommitFailed);
|
||||
consumers.put(GlobalStatus.RollbackFailed.name(), this::processGlobalStatusRollbackFailed);
|
||||
consumers.put(GlobalStatus.TimeoutRollbacked.name(), this::processGlobalStatusTimeoutRollbacked);
|
||||
consumers.put(GlobalStatus.TimeoutRollbackFailed.name(), this::processGlobalStatusTimeoutRollbackFailed);
|
||||
public MetricsSubscriber(Registry registry) {
|
||||
this.registry = registry;
|
||||
consumers = new HashMap<>();
|
||||
consumers.put(GlobalStatus.Begin.name(), this::processGlobalStatusBegin);
|
||||
consumers.put(GlobalStatus.Committed.name(), this::processGlobalStatusCommitted);
|
||||
consumers.put(GlobalStatus.Rollbacked.name(), this::processGlobalStatusRollbacked);
|
||||
|
||||
consumers.put(GlobalStatus.CommitRetryTimeout.name(), this::processGlobalStatusCommitRetryTimeout);
|
||||
consumers.put(GlobalStatus.RollbackRetryTimeout.name(), this::processGlobalStatusTimeoutRollbackRetryTimeout);
|
||||
consumers.put(GlobalStatus.CommitFailed.name(), this::processGlobalStatusCommitFailed);
|
||||
consumers.put(GlobalStatus.RollbackFailed.name(), this::processGlobalStatusRollbackFailed);
|
||||
consumers.put(GlobalStatus.TimeoutRollbacked.name(), this::processGlobalStatusTimeoutRollbacked);
|
||||
consumers.put(GlobalStatus.TimeoutRollbackFailed.name(), this::processGlobalStatusTimeoutRollbackFailed);
|
||||
|
||||
consumers.put(STATUS_VALUE_AFTER_COMMITTED_KEY, this::processAfterGlobalCommitted);
|
||||
consumers.put(STATUS_VALUE_AFTER_ROLLBACKED_KEY, this::processAfterGlobalRollbacked);
|
||||
}
|
||||
consumers.put(GlobalStatus.CommitRetryTimeout.name(), this::processGlobalStatusCommitRetryTimeout);
|
||||
consumers.put(GlobalStatus.RollbackRetryTimeout.name(), this::processGlobalStatusTimeoutRollbackRetryTimeout);
|
||||
|
||||
private void processGlobalStatusBegin(GlobalTransactionEvent event) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("accept new event,xid:{},event:{}", event.getId(), event);
|
||||
for (Object object : EventBusManager.get().getSubscribers()) {
|
||||
LOGGER.debug("subscribe:{},threadName:{}", object.toString(), Thread.currentThread().getName());
|
||||
}
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ACTIVE.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
}
|
||||
consumers.put(STATUS_VALUE_AFTER_COMMITTED_KEY, this::processAfterGlobalCommitted);
|
||||
consumers.put(STATUS_VALUE_AFTER_ROLLBACKED_KEY, this::processAfterGlobalRollbacked);
|
||||
}
|
||||
|
||||
private void processGlobalStatusCommitted(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal()) {
|
||||
return;
|
||||
}
|
||||
decreaseActive(event);
|
||||
registry.getCounter(MeterIdConstants.COUNTER_COMMITTED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_COMMITTED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_COMMITTED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
private void processGlobalStatusBegin(GlobalTransactionEvent event) {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("accept new event,xid:{},event:{}", event.getId(), event);
|
||||
for (Object object : EventBusManager.get().getSubscribers()) {
|
||||
LOGGER.debug("subscribe:{},threadName:{}", object.toString(), Thread.currentThread().getName());
|
||||
}
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ACTIVE.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
}
|
||||
|
||||
private void processGlobalStatusRollbacked(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal()) {
|
||||
return;
|
||||
}
|
||||
decreaseActive(event);
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ROLLBACKED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_ROLLBACKED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_ROLLBACK
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
private void processGlobalStatusCommitted(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal()) {
|
||||
return;
|
||||
}
|
||||
decreaseActive(event);
|
||||
registry.getCounter(MeterIdConstants.COUNTER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void processAfterGlobalRollbacked(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal() && event.isRetryBranch()) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_AFTER_ROLLBACKED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_AFTER_ROLLBACKED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_AFTER_ROLLBACKED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
private void processGlobalStatusRollbacked(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal()) {
|
||||
return;
|
||||
}
|
||||
decreaseActive(event);
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_ROLLBACK.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void processAfterGlobalCommitted(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal() && event.isRetryBranch()) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_AFTER_COMMITTED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_AFTER_COMMITTED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_AFTER_COMMITTED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
private void processAfterGlobalRollbacked(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal() && event.isRetryBranch()) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_AFTER_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_AFTER_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_AFTER_ROLLBACKED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void processGlobalStatusCommitFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportFailed(event);
|
||||
}
|
||||
private void processAfterGlobalCommitted(GlobalTransactionEvent event) {
|
||||
if (event.isRetryGlobal() && event.isRetryBranch()) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
registry.getCounter(MeterIdConstants.COUNTER_AFTER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_AFTER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_AFTER_COMMITTED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void processGlobalStatusRollbackFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportFailed(event);
|
||||
}
|
||||
private void processGlobalStatusCommitFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportFailed(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusTimeoutRollbacked(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
private void processGlobalStatusRollbackFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportFailed(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusTimeoutRollbackFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportTwoPhaseTimeout(event);
|
||||
}
|
||||
private void processGlobalStatusTimeoutRollbacked(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusCommitRetryTimeout(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportTwoPhaseTimeout(event);
|
||||
}
|
||||
private void processGlobalStatusTimeoutRollbackFailed(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportTwoPhaseTimeout(event);
|
||||
}
|
||||
|
||||
private void processGlobalStatusTimeoutRollbackRetryTimeout(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
private void processGlobalStatusCommitRetryTimeout(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
reportTwoPhaseTimeout(event);
|
||||
}
|
||||
|
||||
private void decreaseActive(GlobalTransactionEvent event) {
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ACTIVE
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).decrease(1);
|
||||
}
|
||||
private void processGlobalStatusTimeoutRollbackRetryTimeout(GlobalTransactionEvent event) {
|
||||
decreaseActive(event);
|
||||
}
|
||||
|
||||
private void reportFailed(GlobalTransactionEvent event) {
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_FAILED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_FAILED
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup()))
|
||||
.record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
private void decreaseActive(GlobalTransactionEvent event) {
|
||||
registry.getCounter(MeterIdConstants.COUNTER_ACTIVE.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).decrease(1);
|
||||
}
|
||||
|
||||
private void reportTwoPhaseTimeout(GlobalTransactionEvent event) {
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_TWO_PHASE_TIMEOUT
|
||||
.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
}
|
||||
private void reportFailed(GlobalTransactionEvent event) {
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_FAILED.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
registry.getTimer(MeterIdConstants.TIMER_FAILED.withTag(APP_ID_KEY, event.getApplicationId()).withTag(GROUP_KEY,
|
||||
event.getGroup())).record(event.getEndTime() - event.getBeginTime(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void reportTwoPhaseTimeout(GlobalTransactionEvent event) {
|
||||
registry.getSummary(MeterIdConstants.SUMMARY_TWO_PHASE_TIMEOUT.withTag(APP_ID_KEY, event.getApplicationId())
|
||||
.withTag(GROUP_KEY, event.getGroup())).increase(1);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void recordGlobalTransactionEventForMetrics(GlobalTransactionEvent event) {
|
||||
if (registry != null && consumers.containsKey(event.getStatus())) {
|
||||
consumers.get(event.getStatus()).accept(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void recordGlobalTransactionEventForMetrics(GlobalTransactionEvent event) {
|
||||
if (registry != null && consumers.containsKey(event.getStatus())) {
|
||||
consumers.get(event.getStatus()).accept(event);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this.getClass().getName().equals(obj.getClass().getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this.getClass().getName().equals(obj.getClass().getName());
|
||||
}
|
||||
/**
|
||||
* PMD check SuppressWarnings("checkstyle:EqualsHashCode")
|
||||
* @return the hash code
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* PMD check
|
||||
* SuppressWarnings("checkstyle:EqualsHashCode")
|
||||
* @return the hash code
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
}
|
||||
+147
-142
@@ -33,167 +33,172 @@ import org.slf4j.LoggerFactory;
|
||||
*/
|
||||
public abstract class AbstractSessionManager implements SessionManager, SessionLifecycleListener {
|
||||
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractSessionManager.class);
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(AbstractSessionManager.class);
|
||||
|
||||
/**
|
||||
* The Transaction store manager.
|
||||
*/
|
||||
protected TransactionStoreManager transactionStoreManager;
|
||||
/**
|
||||
* The Transaction store manager.
|
||||
*/
|
||||
protected TransactionStoreManager transactionStoreManager;
|
||||
|
||||
/**
|
||||
* The Name.
|
||||
*/
|
||||
protected String name;
|
||||
/**
|
||||
* The Name.
|
||||
*/
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract session manager.
|
||||
*/
|
||||
public AbstractSessionManager() {
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Abstract session manager.
|
||||
*/
|
||||
public AbstractSessionManager() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Abstract session manager.
|
||||
*
|
||||
* @param name the name
|
||||
*/
|
||||
public AbstractSessionManager(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Abstract session manager.
|
||||
* @param name the name
|
||||
*/
|
||||
public AbstractSessionManager(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_ADD);
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_ADD, session);
|
||||
}
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_ADD);
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_ADD, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_UPDATE);
|
||||
}
|
||||
if (GlobalStatus.Rollbacking == status) {
|
||||
session.getBranchSessions().forEach(i -> i.setLockStatus(LockStatus.Rollbacking));
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
}
|
||||
@Override
|
||||
public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_UPDATE);
|
||||
}
|
||||
if (GlobalStatus.Rollbacking == status) {
|
||||
session.getBranchSessions().forEach(i -> i.setLockStatus(LockStatus.Rollbacking));
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_REMOVE);
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_REMOVE, session);
|
||||
}
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, session, LogOperation.GLOBAL_REMOVE);
|
||||
}
|
||||
writeSession(LogOperation.GLOBAL_REMOVE, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBranchSession(GlobalSession session, BranchSession branchSession) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_ADD);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_ADD, branchSession);
|
||||
}
|
||||
@Override
|
||||
public void addBranchSession(GlobalSession session, BranchSession branchSession) throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_ADD);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_ADD, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBranchSessionStatus(BranchSession branchSession, BranchStatus status)
|
||||
throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_UPDATE);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_UPDATE, branchSession);
|
||||
}
|
||||
@Override
|
||||
public void updateBranchSessionStatus(BranchSession branchSession, BranchStatus status)
|
||||
throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_UPDATE);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_UPDATE, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBranchSession(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_REMOVE);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_REMOVE, branchSession);
|
||||
}
|
||||
@Override
|
||||
public void removeBranchSession(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
if (LOGGER.isDebugEnabled()) {
|
||||
LOGGER.debug("MANAGER[{}] SESSION[{}] {}", name, branchSession, LogOperation.BRANCH_REMOVE);
|
||||
}
|
||||
writeSession(LogOperation.BRANCH_REMOVE, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBegin(GlobalSession globalSession) throws TransactionException {
|
||||
addGlobalSession(globalSession);
|
||||
}
|
||||
@Override
|
||||
public void onBegin(GlobalSession globalSession) throws TransactionException {
|
||||
addGlobalSession(globalSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChange(GlobalSession globalSession, GlobalStatus status) throws TransactionException {
|
||||
updateGlobalSessionStatus(globalSession, status);
|
||||
}
|
||||
@Override
|
||||
public void onStatusChange(GlobalSession globalSession, GlobalStatus status) throws TransactionException {
|
||||
updateGlobalSessionStatus(globalSession, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBranchStatusChange(GlobalSession globalSession, BranchSession branchSession, BranchStatus status)
|
||||
throws TransactionException {
|
||||
updateBranchSessionStatus(branchSession, status);
|
||||
}
|
||||
@Override
|
||||
public void onBranchStatusChange(GlobalSession globalSession, BranchSession branchSession, BranchStatus status)
|
||||
throws TransactionException {
|
||||
updateBranchSessionStatus(branchSession, status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAddBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
addBranchSession(globalSession, branchSession);
|
||||
}
|
||||
@Override
|
||||
public void onAddBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
addBranchSession(globalSession, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoveBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
removeBranchSession(globalSession, branchSession);
|
||||
}
|
||||
@Override
|
||||
public void onRemoveBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException {
|
||||
removeBranchSession(globalSession, branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(GlobalSession globalSession) throws TransactionException {
|
||||
globalSession.setActive(false);
|
||||
}
|
||||
@Override
|
||||
public void onClose(GlobalSession globalSession) throws TransactionException {
|
||||
globalSession.setActive(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccessEnd(GlobalSession globalSession) throws TransactionException {
|
||||
removeGlobalSession(globalSession);
|
||||
}
|
||||
@Override
|
||||
public void onSuccessEnd(GlobalSession globalSession) throws TransactionException {
|
||||
removeGlobalSession(globalSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailEnd(GlobalSession globalSession) throws TransactionException {
|
||||
LOGGER.info("xid:{} fail end, transaction:{}",globalSession.getXid(),globalSession.toString());
|
||||
}
|
||||
@Override
|
||||
public void onFailEnd(GlobalSession globalSession) throws TransactionException {
|
||||
LOGGER.info("xid:{} fail end, transaction:{}", globalSession.getXid(), globalSession.toString());
|
||||
}
|
||||
|
||||
private void writeSession(LogOperation logOperation, SessionStorable sessionStorable) throws TransactionException {
|
||||
if (!transactionStoreManager.writeSession(logOperation, sessionStorable)) {
|
||||
if (LogOperation.GLOBAL_ADD.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to store global session");
|
||||
} else if (LogOperation.GLOBAL_UPDATE.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to update global session");
|
||||
} else if (LogOperation.GLOBAL_REMOVE.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to remove global session");
|
||||
} else if (LogOperation.BRANCH_ADD.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to store branch session");
|
||||
} else if (LogOperation.BRANCH_UPDATE.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to update branch session");
|
||||
} else if (LogOperation.BRANCH_REMOVE.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to remove branch session");
|
||||
} else {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Unknown LogOperation:" + logOperation.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
private void writeSession(LogOperation logOperation, SessionStorable sessionStorable) throws TransactionException {
|
||||
if (!transactionStoreManager.writeSession(logOperation, sessionStorable)) {
|
||||
if (LogOperation.GLOBAL_ADD.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to store global session");
|
||||
}
|
||||
else if (LogOperation.GLOBAL_UPDATE.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to update global session");
|
||||
}
|
||||
else if (LogOperation.GLOBAL_REMOVE.equals(logOperation)) {
|
||||
throw new GlobalTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to remove global session");
|
||||
}
|
||||
else if (LogOperation.BRANCH_ADD.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to store branch session");
|
||||
}
|
||||
else if (LogOperation.BRANCH_UPDATE.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to update branch session");
|
||||
}
|
||||
else if (LogOperation.BRANCH_REMOVE.equals(logOperation)) {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Fail to remove branch session");
|
||||
}
|
||||
else {
|
||||
throw new BranchTransactionException(TransactionExceptionCode.FailedWriteSession,
|
||||
"Unknown LogOperation:" + logOperation.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transaction store manager.
|
||||
* @param transactionStoreManager the transaction store manager
|
||||
*/
|
||||
public void setTransactionStoreManager(TransactionStoreManager transactionStoreManager) {
|
||||
this.transactionStoreManager = transactionStoreManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transaction store manager.
|
||||
*
|
||||
* @param transactionStoreManager the transaction store manager
|
||||
*/
|
||||
public void setTransactionStoreManager(TransactionStoreManager transactionStoreManager) {
|
||||
this.transactionStoreManager = transactionStoreManager;
|
||||
}
|
||||
}
|
||||
+407
-423
@@ -42,428 +42,412 @@ import static io.seata.core.model.LockStatus.Locked;
|
||||
*/
|
||||
public class BranchSession implements Lockable, Comparable<BranchSession>, SessionStorable {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(BranchSession.class);
|
||||
|
||||
private static final int MAX_BRANCH_SESSION_SIZE = StoreConfig.getMaxBranchSessionSize();
|
||||
|
||||
private static ThreadLocal<ByteBuffer> byteBufferThreadLocal = ThreadLocal.withInitial(() -> ByteBuffer.allocate(
|
||||
MAX_BRANCH_SESSION_SIZE));
|
||||
|
||||
private String xid;
|
||||
|
||||
private long transactionId;
|
||||
|
||||
private long branchId;
|
||||
|
||||
private String resourceGroupId;
|
||||
|
||||
private String resourceId;
|
||||
|
||||
private String lockKey;
|
||||
|
||||
private BranchType branchType;
|
||||
|
||||
private BranchStatus status = BranchStatus.Unknown;
|
||||
|
||||
private String clientId;
|
||||
|
||||
private String applicationData;
|
||||
|
||||
private LockStatus lockStatus = Locked;
|
||||
|
||||
private ConcurrentMap<FileLocker.BucketLockMap, Set<String>> lockHolder
|
||||
= new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets application data.
|
||||
*
|
||||
* @return the application data
|
||||
*/
|
||||
public String getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets application data.
|
||||
*
|
||||
* @param applicationData the application data
|
||||
*/
|
||||
public void setApplicationData(String applicationData) {
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource group id.
|
||||
*
|
||||
* @return the resource group id
|
||||
*/
|
||||
public String getResourceGroupId() {
|
||||
return resourceGroupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets resource group id.
|
||||
*
|
||||
* @param resourceGroupId the resource group id
|
||||
*/
|
||||
public void setResourceGroupId(String resourceGroupId) {
|
||||
this.resourceGroupId = resourceGroupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets client id.
|
||||
*
|
||||
* @return the client id
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets client id.
|
||||
*
|
||||
* @param clientId the client id
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource id.
|
||||
*
|
||||
* @return the resource id
|
||||
*/
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets resource id.
|
||||
*
|
||||
* @param resourceId the resource id
|
||||
*/
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock key.
|
||||
*
|
||||
* @return the lock key
|
||||
*/
|
||||
public String getLockKey() {
|
||||
return lockKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets lock key.
|
||||
*
|
||||
* @param lockKey the lock key
|
||||
*/
|
||||
public void setLockKey(String lockKey) {
|
||||
this.lockKey = lockKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets branch type.
|
||||
*
|
||||
* @return the branch type
|
||||
*/
|
||||
public BranchType getBranchType() {
|
||||
return branchType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets branch type.
|
||||
*
|
||||
* @param branchType the branch type
|
||||
*/
|
||||
public void setBranchType(BranchType branchType) {
|
||||
this.branchType = branchType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets status.
|
||||
*
|
||||
* @return the status
|
||||
*/
|
||||
public BranchStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets status.
|
||||
*
|
||||
* @param status the status
|
||||
*/
|
||||
public void setStatus(BranchStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets transaction id.
|
||||
*
|
||||
* @return the transaction id
|
||||
*/
|
||||
public long getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transaction id.
|
||||
*
|
||||
* @param transactionId the transaction id
|
||||
*/
|
||||
public void setTransactionId(long transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets branch id.
|
||||
*
|
||||
* @return the branch id
|
||||
*/
|
||||
public long getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets branch id.
|
||||
*
|
||||
* @param branchId the branch id
|
||||
*/
|
||||
public void setBranchId(long branchId) {
|
||||
this.branchId = branchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets xid.
|
||||
*
|
||||
* @return the xid
|
||||
*/
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets xid.
|
||||
*
|
||||
* @param xid the xid
|
||||
*/
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BR:" + branchId + "/" + transactionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BranchSession o) {
|
||||
return Long.compare(this.branchId, o.branchId);
|
||||
}
|
||||
|
||||
public boolean canBeCommittedAsync() {
|
||||
return branchType == BranchType.AT || status == BranchStatus.PhaseOne_Failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock holder.
|
||||
*
|
||||
* @return the lock holder
|
||||
*/
|
||||
public ConcurrentMap<FileLocker.BucketLockMap, Set<String>> getLockHolder() {
|
||||
return lockHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lock() throws TransactionException {
|
||||
return this.lock(true, false);
|
||||
}
|
||||
|
||||
public boolean lock(boolean autoCommit, boolean skipCheckLock) throws TransactionException {
|
||||
if (this.getBranchType().equals(BranchType.AT)) {
|
||||
return LockerManagerFactory.getLockManager().acquireLock(this, autoCommit, skipCheckLock);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlock() throws TransactionException {
|
||||
if (this.getBranchType() == BranchType.AT) {
|
||||
return LockerManagerFactory.getLockManager().releaseLock(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public LockStatus getLockStatus() {
|
||||
return lockStatus;
|
||||
}
|
||||
|
||||
public void setLockStatus(LockStatus lockStatus) {
|
||||
this.lockStatus = lockStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
|
||||
byte[] resourceIdBytes = resourceId != null ? resourceId.getBytes() : null;
|
||||
|
||||
byte[] lockKeyBytes = lockKey != null ? lockKey.getBytes() : null;
|
||||
|
||||
byte[] clientIdBytes = clientId != null ? clientId.getBytes() : null;
|
||||
|
||||
byte[] applicationDataBytes = applicationData != null ? applicationData.getBytes() : null;
|
||||
|
||||
byte[] xidBytes = xid != null ? xid.getBytes() : null;
|
||||
|
||||
byte branchTypeByte = branchType != null ? (byte) branchType.ordinal() : -1;
|
||||
|
||||
int size = calBranchSessionSize(resourceIdBytes, lockKeyBytes, clientIdBytes, applicationDataBytes, xidBytes);
|
||||
|
||||
if (size > MAX_BRANCH_SESSION_SIZE) {
|
||||
if (lockKeyBytes == null) {
|
||||
throw new RuntimeException("branch session size exceeded, size : " + size + " maxBranchSessionSize : "
|
||||
+ MAX_BRANCH_SESSION_SIZE);
|
||||
}
|
||||
// try compress lockkey
|
||||
try {
|
||||
size -= lockKeyBytes.length;
|
||||
lockKeyBytes = CompressUtil.compress(lockKeyBytes);
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("compress lockKey error", e);
|
||||
} finally {
|
||||
size += lockKeyBytes.length;
|
||||
}
|
||||
|
||||
if (size > MAX_BRANCH_SESSION_SIZE) {
|
||||
throw new RuntimeException(
|
||||
"compress branch session size exceeded, compressSize : " + size + " maxBranchSessionSize : "
|
||||
+ MAX_BRANCH_SESSION_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer byteBuffer = byteBufferThreadLocal.get();
|
||||
//recycle
|
||||
byteBuffer.clear();
|
||||
|
||||
byteBuffer.putLong(transactionId);
|
||||
byteBuffer.putLong(branchId);
|
||||
|
||||
if (resourceIdBytes != null) {
|
||||
byteBuffer.putInt(resourceIdBytes.length);
|
||||
byteBuffer.put(resourceIdBytes);
|
||||
} else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (lockKeyBytes != null) {
|
||||
byteBuffer.putInt(lockKeyBytes.length);
|
||||
byteBuffer.put(lockKeyBytes);
|
||||
} else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (clientIdBytes != null) {
|
||||
byteBuffer.putShort((short)clientIdBytes.length);
|
||||
byteBuffer.put(clientIdBytes);
|
||||
} else {
|
||||
byteBuffer.putShort((short)0);
|
||||
}
|
||||
|
||||
if (applicationDataBytes != null) {
|
||||
byteBuffer.putInt(applicationDataBytes.length);
|
||||
byteBuffer.put(applicationDataBytes);
|
||||
} else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (xidBytes != null) {
|
||||
byteBuffer.putInt(xidBytes.length);
|
||||
byteBuffer.put(xidBytes);
|
||||
} else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
byteBuffer.put(branchTypeByte);
|
||||
|
||||
byteBuffer.put((byte)status.getCode());
|
||||
byteBuffer.put((byte)lockStatus.getCode());
|
||||
byteBuffer.flip();
|
||||
byte[] result = new byte[byteBuffer.limit()];
|
||||
byteBuffer.get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private int calBranchSessionSize(byte[] resourceIdBytes, byte[] lockKeyBytes, byte[] clientIdBytes,
|
||||
byte[] applicationDataBytes, byte[] xidBytes) {
|
||||
final int size = 8 // trascationId
|
||||
+ 8 // branchId
|
||||
+ 4 // resourceIdBytes.length
|
||||
+ 4 // lockKeyBytes.length
|
||||
+ 2 // clientIdBytes.length
|
||||
+ 4 // applicationDataBytes.length
|
||||
+ 4 // xidBytes.size
|
||||
+ 1 // statusCode
|
||||
+ (resourceIdBytes == null ? 0 : resourceIdBytes.length)
|
||||
+ (lockKeyBytes == null ? 0 : lockKeyBytes.length)
|
||||
+ (clientIdBytes == null ? 0 : clientIdBytes.length)
|
||||
+ (applicationDataBytes == null ? 0 : applicationDataBytes.length)
|
||||
+ (xidBytes == null ? 0 : xidBytes.length)
|
||||
+ 1; //branchType
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] a) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(a);
|
||||
this.transactionId = byteBuffer.getLong();
|
||||
this.branchId = byteBuffer.getLong();
|
||||
int resourceLen = byteBuffer.getInt();
|
||||
if (resourceLen > 0) {
|
||||
byte[] byResource = new byte[resourceLen];
|
||||
byteBuffer.get(byResource);
|
||||
this.resourceId = new String(byResource);
|
||||
}
|
||||
int lockKeyLen = byteBuffer.getInt();
|
||||
if (lockKeyLen > 0) {
|
||||
byte[] byLockKey = new byte[lockKeyLen];
|
||||
byteBuffer.get(byLockKey);
|
||||
if (CompressUtil.isCompressData(byLockKey)) {
|
||||
try {
|
||||
this.lockKey = new String(CompressUtil.uncompress(byLockKey));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("decompress lockKey error", e);
|
||||
}
|
||||
} else {
|
||||
this.lockKey = new String(byLockKey);
|
||||
}
|
||||
|
||||
}
|
||||
short clientIdLen = byteBuffer.getShort();
|
||||
if (clientIdLen > 0) {
|
||||
byte[] byClientId = new byte[clientIdLen];
|
||||
byteBuffer.get(byClientId);
|
||||
this.clientId = new String(byClientId);
|
||||
}
|
||||
int applicationDataLen = byteBuffer.getInt();
|
||||
if (applicationDataLen > 0) {
|
||||
byte[] byApplicationData = new byte[applicationDataLen];
|
||||
byteBuffer.get(byApplicationData);
|
||||
this.applicationData = new String(byApplicationData);
|
||||
}
|
||||
int xidLen = byteBuffer.getInt();
|
||||
if (xidLen > 0) {
|
||||
byte[] xidBytes = new byte[xidLen];
|
||||
byteBuffer.get(xidBytes);
|
||||
this.xid = new String(xidBytes);
|
||||
}
|
||||
int branchTypeId = byteBuffer.get();
|
||||
if (branchTypeId >= 0) {
|
||||
this.branchType = BranchType.values()[branchTypeId];
|
||||
}
|
||||
this.status = BranchStatus.get(byteBuffer.get());
|
||||
}
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(BranchSession.class);
|
||||
|
||||
private static final int MAX_BRANCH_SESSION_SIZE = StoreConfig.getMaxBranchSessionSize();
|
||||
|
||||
private static ThreadLocal<ByteBuffer> byteBufferThreadLocal = ThreadLocal
|
||||
.withInitial(() -> ByteBuffer.allocate(MAX_BRANCH_SESSION_SIZE));
|
||||
|
||||
private String xid;
|
||||
|
||||
private long transactionId;
|
||||
|
||||
private long branchId;
|
||||
|
||||
private String resourceGroupId;
|
||||
|
||||
private String resourceId;
|
||||
|
||||
private String lockKey;
|
||||
|
||||
private BranchType branchType;
|
||||
|
||||
private BranchStatus status = BranchStatus.Unknown;
|
||||
|
||||
private String clientId;
|
||||
|
||||
private String applicationData;
|
||||
|
||||
private LockStatus lockStatus = Locked;
|
||||
|
||||
private ConcurrentMap<FileLocker.BucketLockMap, Set<String>> lockHolder = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* Gets application data.
|
||||
* @return the application data
|
||||
*/
|
||||
public String getApplicationData() {
|
||||
return applicationData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets application data.
|
||||
* @param applicationData the application data
|
||||
*/
|
||||
public void setApplicationData(String applicationData) {
|
||||
this.applicationData = applicationData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource group id.
|
||||
* @return the resource group id
|
||||
*/
|
||||
public String getResourceGroupId() {
|
||||
return resourceGroupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets resource group id.
|
||||
* @param resourceGroupId the resource group id
|
||||
*/
|
||||
public void setResourceGroupId(String resourceGroupId) {
|
||||
this.resourceGroupId = resourceGroupId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets client id.
|
||||
* @return the client id
|
||||
*/
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets client id.
|
||||
* @param clientId the client id
|
||||
*/
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets resource id.
|
||||
* @return the resource id
|
||||
*/
|
||||
public String getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets resource id.
|
||||
* @param resourceId the resource id
|
||||
*/
|
||||
public void setResourceId(String resourceId) {
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock key.
|
||||
* @return the lock key
|
||||
*/
|
||||
public String getLockKey() {
|
||||
return lockKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets lock key.
|
||||
* @param lockKey the lock key
|
||||
*/
|
||||
public void setLockKey(String lockKey) {
|
||||
this.lockKey = lockKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets branch type.
|
||||
* @return the branch type
|
||||
*/
|
||||
public BranchType getBranchType() {
|
||||
return branchType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets branch type.
|
||||
* @param branchType the branch type
|
||||
*/
|
||||
public void setBranchType(BranchType branchType) {
|
||||
this.branchType = branchType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets status.
|
||||
* @return the status
|
||||
*/
|
||||
public BranchStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets status.
|
||||
* @param status the status
|
||||
*/
|
||||
public void setStatus(BranchStatus status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets transaction id.
|
||||
* @return the transaction id
|
||||
*/
|
||||
public long getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transaction id.
|
||||
* @param transactionId the transaction id
|
||||
*/
|
||||
public void setTransactionId(long transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets branch id.
|
||||
* @return the branch id
|
||||
*/
|
||||
public long getBranchId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets branch id.
|
||||
* @param branchId the branch id
|
||||
*/
|
||||
public void setBranchId(long branchId) {
|
||||
this.branchId = branchId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets xid.
|
||||
* @return the xid
|
||||
*/
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets xid.
|
||||
* @param xid the xid
|
||||
*/
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BR:" + branchId + "/" + transactionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BranchSession o) {
|
||||
return Long.compare(this.branchId, o.branchId);
|
||||
}
|
||||
|
||||
public boolean canBeCommittedAsync() {
|
||||
return branchType == BranchType.AT || status == BranchStatus.PhaseOne_Failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets lock holder.
|
||||
* @return the lock holder
|
||||
*/
|
||||
public ConcurrentMap<FileLocker.BucketLockMap, Set<String>> getLockHolder() {
|
||||
return lockHolder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lock() throws TransactionException {
|
||||
return this.lock(true, false);
|
||||
}
|
||||
|
||||
public boolean lock(boolean autoCommit, boolean skipCheckLock) throws TransactionException {
|
||||
if (this.getBranchType().equals(BranchType.AT)) {
|
||||
return LockerManagerFactory.getLockManager().acquireLock(this, autoCommit, skipCheckLock);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unlock() throws TransactionException {
|
||||
if (this.getBranchType() == BranchType.AT) {
|
||||
return LockerManagerFactory.getLockManager().releaseLock(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public LockStatus getLockStatus() {
|
||||
return lockStatus;
|
||||
}
|
||||
|
||||
public void setLockStatus(LockStatus lockStatus) {
|
||||
this.lockStatus = lockStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
|
||||
byte[] resourceIdBytes = resourceId != null ? resourceId.getBytes() : null;
|
||||
|
||||
byte[] lockKeyBytes = lockKey != null ? lockKey.getBytes() : null;
|
||||
|
||||
byte[] clientIdBytes = clientId != null ? clientId.getBytes() : null;
|
||||
|
||||
byte[] applicationDataBytes = applicationData != null ? applicationData.getBytes() : null;
|
||||
|
||||
byte[] xidBytes = xid != null ? xid.getBytes() : null;
|
||||
|
||||
byte branchTypeByte = branchType != null ? (byte) branchType.ordinal() : -1;
|
||||
|
||||
int size = calBranchSessionSize(resourceIdBytes, lockKeyBytes, clientIdBytes, applicationDataBytes, xidBytes);
|
||||
|
||||
if (size > MAX_BRANCH_SESSION_SIZE) {
|
||||
if (lockKeyBytes == null) {
|
||||
throw new RuntimeException("branch session size exceeded, size : " + size + " maxBranchSessionSize : "
|
||||
+ MAX_BRANCH_SESSION_SIZE);
|
||||
}
|
||||
// try compress lockkey
|
||||
try {
|
||||
size -= lockKeyBytes.length;
|
||||
lockKeyBytes = CompressUtil.compress(lockKeyBytes);
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOGGER.error("compress lockKey error", e);
|
||||
}
|
||||
finally {
|
||||
size += lockKeyBytes.length;
|
||||
}
|
||||
|
||||
if (size > MAX_BRANCH_SESSION_SIZE) {
|
||||
throw new RuntimeException("compress branch session size exceeded, compressSize : " + size
|
||||
+ " maxBranchSessionSize : " + MAX_BRANCH_SESSION_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
ByteBuffer byteBuffer = byteBufferThreadLocal.get();
|
||||
// recycle
|
||||
byteBuffer.clear();
|
||||
|
||||
byteBuffer.putLong(transactionId);
|
||||
byteBuffer.putLong(branchId);
|
||||
|
||||
if (resourceIdBytes != null) {
|
||||
byteBuffer.putInt(resourceIdBytes.length);
|
||||
byteBuffer.put(resourceIdBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (lockKeyBytes != null) {
|
||||
byteBuffer.putInt(lockKeyBytes.length);
|
||||
byteBuffer.put(lockKeyBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (clientIdBytes != null) {
|
||||
byteBuffer.putShort((short) clientIdBytes.length);
|
||||
byteBuffer.put(clientIdBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putShort((short) 0);
|
||||
}
|
||||
|
||||
if (applicationDataBytes != null) {
|
||||
byteBuffer.putInt(applicationDataBytes.length);
|
||||
byteBuffer.put(applicationDataBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
if (xidBytes != null) {
|
||||
byteBuffer.putInt(xidBytes.length);
|
||||
byteBuffer.put(xidBytes);
|
||||
}
|
||||
else {
|
||||
byteBuffer.putInt(0);
|
||||
}
|
||||
|
||||
byteBuffer.put(branchTypeByte);
|
||||
|
||||
byteBuffer.put((byte) status.getCode());
|
||||
byteBuffer.put((byte) lockStatus.getCode());
|
||||
byteBuffer.flip();
|
||||
byte[] result = new byte[byteBuffer.limit()];
|
||||
byteBuffer.get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private int calBranchSessionSize(byte[] resourceIdBytes, byte[] lockKeyBytes, byte[] clientIdBytes,
|
||||
byte[] applicationDataBytes, byte[] xidBytes) {
|
||||
final int size = 8 // trascationId
|
||||
+ 8 // branchId
|
||||
+ 4 // resourceIdBytes.length
|
||||
+ 4 // lockKeyBytes.length
|
||||
+ 2 // clientIdBytes.length
|
||||
+ 4 // applicationDataBytes.length
|
||||
+ 4 // xidBytes.size
|
||||
+ 1 // statusCode
|
||||
+ (resourceIdBytes == null ? 0 : resourceIdBytes.length)
|
||||
+ (lockKeyBytes == null ? 0 : lockKeyBytes.length) + (clientIdBytes == null ? 0 : clientIdBytes.length)
|
||||
+ (applicationDataBytes == null ? 0 : applicationDataBytes.length)
|
||||
+ (xidBytes == null ? 0 : xidBytes.length) + 1; // branchType
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] a) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(a);
|
||||
this.transactionId = byteBuffer.getLong();
|
||||
this.branchId = byteBuffer.getLong();
|
||||
int resourceLen = byteBuffer.getInt();
|
||||
if (resourceLen > 0) {
|
||||
byte[] byResource = new byte[resourceLen];
|
||||
byteBuffer.get(byResource);
|
||||
this.resourceId = new String(byResource);
|
||||
}
|
||||
int lockKeyLen = byteBuffer.getInt();
|
||||
if (lockKeyLen > 0) {
|
||||
byte[] byLockKey = new byte[lockKeyLen];
|
||||
byteBuffer.get(byLockKey);
|
||||
if (CompressUtil.isCompressData(byLockKey)) {
|
||||
try {
|
||||
this.lockKey = new String(CompressUtil.uncompress(byLockKey));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException("decompress lockKey error", e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.lockKey = new String(byLockKey);
|
||||
}
|
||||
|
||||
}
|
||||
short clientIdLen = byteBuffer.getShort();
|
||||
if (clientIdLen > 0) {
|
||||
byte[] byClientId = new byte[clientIdLen];
|
||||
byteBuffer.get(byClientId);
|
||||
this.clientId = new String(byClientId);
|
||||
}
|
||||
int applicationDataLen = byteBuffer.getInt();
|
||||
if (applicationDataLen > 0) {
|
||||
byte[] byApplicationData = new byte[applicationDataLen];
|
||||
byteBuffer.get(byApplicationData);
|
||||
this.applicationData = new String(byApplicationData);
|
||||
}
|
||||
int xidLen = byteBuffer.getInt();
|
||||
if (xidLen > 0) {
|
||||
byte[] xidBytes = new byte[xidLen];
|
||||
byteBuffer.get(xidBytes);
|
||||
this.xid = new String(xidBytes);
|
||||
}
|
||||
int branchTypeId = byteBuffer.get();
|
||||
if (branchTypeId >= 0) {
|
||||
this.branchType = BranchType.values()[branchTypeId];
|
||||
}
|
||||
this.status = BranchStatus.get(byteBuffer.get());
|
||||
}
|
||||
|
||||
}
|
||||
+9
-9
@@ -26,14 +26,14 @@ import io.seata.core.exception.TransactionException;
|
||||
@FunctionalInterface
|
||||
public interface BranchSessionHandler {
|
||||
|
||||
Boolean CONTINUE = null;
|
||||
Boolean CONTINUE = null;
|
||||
|
||||
/**
|
||||
* Handle branch session.
|
||||
* @param branchSession the branch session
|
||||
* @return the handle result
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
Boolean handle(BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Handle branch session.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @return the handle result
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
Boolean handle(BranchSession branchSession) throws TransactionException;
|
||||
}
|
||||
+701
-716
File diff suppressed because it is too large.
Load diff
+7
-7
@@ -26,11 +26,11 @@ import io.seata.core.exception.TransactionException;
|
||||
@FunctionalInterface
|
||||
public interface GlobalSessionHandler {
|
||||
|
||||
/**
|
||||
* Handle global session.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void handle(GlobalSession globalSession) throws TransactionException;
|
||||
/**
|
||||
* Handle global session.
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void handle(GlobalSession globalSession) throws TransactionException;
|
||||
|
||||
}
|
||||
@@ -24,19 +24,18 @@ import io.seata.core.exception.TransactionException;
|
||||
*/
|
||||
public interface Lockable {
|
||||
|
||||
/**
|
||||
* Lock boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean lock() throws TransactionException;
|
||||
/**
|
||||
* Lock boolean.
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean lock() throws TransactionException;
|
||||
|
||||
/**
|
||||
* Unlock boolean.
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean unlock() throws TransactionException;
|
||||
|
||||
/**
|
||||
* Unlock boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
boolean unlock() throws TransactionException;
|
||||
}
|
||||
@@ -22,8 +22,9 @@ package io.seata.server.session;
|
||||
*/
|
||||
public interface Reloadable {
|
||||
|
||||
/**
|
||||
* Reload states.
|
||||
*/
|
||||
void reload();
|
||||
/**
|
||||
* Reload states.
|
||||
*/
|
||||
void reload();
|
||||
|
||||
}
|
||||
+99
-101
@@ -23,123 +23,121 @@ import io.seata.core.model.GlobalStatus;
|
||||
* @author slievrly
|
||||
*/
|
||||
public class SessionCondition {
|
||||
private Long transactionId;
|
||||
private String xid;
|
||||
private GlobalStatus status;
|
||||
private GlobalStatus[] statuses;
|
||||
private Long overTimeAliveMills;
|
||||
private boolean lazyLoadBranch;
|
||||
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
*/
|
||||
public SessionCondition() {
|
||||
}
|
||||
private Long transactionId;
|
||||
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
*
|
||||
* @param xid the xid
|
||||
*/
|
||||
public SessionCondition(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
private String xid;
|
||||
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
*
|
||||
* @param status the status
|
||||
*/
|
||||
public SessionCondition(GlobalStatus status) {
|
||||
this.status = status;
|
||||
this.statuses = new GlobalStatus[] {status};
|
||||
}
|
||||
private GlobalStatus status;
|
||||
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
*
|
||||
* @param statuses the statuses
|
||||
*/
|
||||
public SessionCondition(GlobalStatus... statuses) {
|
||||
this.statuses = statuses;
|
||||
}
|
||||
private GlobalStatus[] statuses;
|
||||
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
*
|
||||
* @param overTimeAliveMills the over time alive mills
|
||||
*/
|
||||
public SessionCondition(long overTimeAliveMills) {
|
||||
this.overTimeAliveMills = overTimeAliveMills;
|
||||
}
|
||||
private Long overTimeAliveMills;
|
||||
|
||||
/**
|
||||
* Gets status.
|
||||
*
|
||||
* @return the status
|
||||
*/
|
||||
public GlobalStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
private boolean lazyLoadBranch;
|
||||
|
||||
/**
|
||||
* Sets status.
|
||||
*
|
||||
* @param status the status
|
||||
*/
|
||||
public void setStatus(GlobalStatus status) {
|
||||
this.status = status;
|
||||
this.statuses = new GlobalStatus[] {status};
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
*/
|
||||
public SessionCondition() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets over time alive mills.
|
||||
*
|
||||
* @return the over time alive mills
|
||||
*/
|
||||
public Long getOverTimeAliveMills() {
|
||||
return overTimeAliveMills;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
* @param xid the xid
|
||||
*/
|
||||
public SessionCondition(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets over time alive mills.
|
||||
*
|
||||
* @param overTimeAliveMills the over time alive mills
|
||||
*/
|
||||
public void setOverTimeAliveMills(Long overTimeAliveMills) {
|
||||
this.overTimeAliveMills = overTimeAliveMills;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
* @param status the status
|
||||
*/
|
||||
public SessionCondition(GlobalStatus status) {
|
||||
this.status = status;
|
||||
this.statuses = new GlobalStatus[] { status };
|
||||
}
|
||||
|
||||
public Long getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
* @param statuses the statuses
|
||||
*/
|
||||
public SessionCondition(GlobalStatus... statuses) {
|
||||
this.statuses = statuses;
|
||||
}
|
||||
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Session condition.
|
||||
* @param overTimeAliveMills the over time alive mills
|
||||
*/
|
||||
public SessionCondition(long overTimeAliveMills) {
|
||||
this.overTimeAliveMills = overTimeAliveMills;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
/**
|
||||
* Gets status.
|
||||
* @return the status
|
||||
*/
|
||||
public GlobalStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
/**
|
||||
* Sets status.
|
||||
* @param status the status
|
||||
*/
|
||||
public void setStatus(GlobalStatus status) {
|
||||
this.status = status;
|
||||
this.statuses = new GlobalStatus[] { status };
|
||||
}
|
||||
|
||||
public GlobalStatus[] getStatuses() {
|
||||
return statuses;
|
||||
}
|
||||
/**
|
||||
* Gets over time alive mills.
|
||||
* @return the over time alive mills
|
||||
*/
|
||||
public Long getOverTimeAliveMills() {
|
||||
return overTimeAliveMills;
|
||||
}
|
||||
|
||||
public void setStatuses(GlobalStatus... statuses) {
|
||||
this.statuses = statuses;
|
||||
}
|
||||
/**
|
||||
* Sets over time alive mills.
|
||||
* @param overTimeAliveMills the over time alive mills
|
||||
*/
|
||||
public void setOverTimeAliveMills(Long overTimeAliveMills) {
|
||||
this.overTimeAliveMills = overTimeAliveMills;
|
||||
}
|
||||
|
||||
public boolean isLazyLoadBranch() {
|
||||
return lazyLoadBranch;
|
||||
}
|
||||
public Long getTransactionId() {
|
||||
return transactionId;
|
||||
}
|
||||
|
||||
public void setLazyLoadBranch(boolean lazyLoadBranch) {
|
||||
this.lazyLoadBranch = lazyLoadBranch;
|
||||
}
|
||||
public void setTransactionId(Long transactionId) {
|
||||
this.transactionId = transactionId;
|
||||
}
|
||||
|
||||
public String getXid() {
|
||||
return xid;
|
||||
}
|
||||
|
||||
public void setXid(String xid) {
|
||||
this.xid = xid;
|
||||
}
|
||||
|
||||
public GlobalStatus[] getStatuses() {
|
||||
return statuses;
|
||||
}
|
||||
|
||||
public void setStatuses(GlobalStatus... statuses) {
|
||||
this.statuses = statuses;
|
||||
}
|
||||
|
||||
public boolean isLazyLoadBranch() {
|
||||
return lazyLoadBranch;
|
||||
}
|
||||
|
||||
public void setLazyLoadBranch(boolean lazyLoadBranch) {
|
||||
this.lazyLoadBranch = lazyLoadBranch;
|
||||
}
|
||||
|
||||
}
|
||||
+259
-253
@@ -45,279 +45,285 @@ import static io.seata.common.DefaultValues.DEFAULT_ENABLE_BRANCH_ASYNC_REMOVE;
|
||||
* @author sharajava
|
||||
*/
|
||||
public class SessionHelper {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SessionHelper.class);
|
||||
|
||||
/**
|
||||
* The constant CONFIG.
|
||||
*/
|
||||
private static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SessionHelper.class);
|
||||
|
||||
private static final Boolean ENABLE_BRANCH_ASYNC_REMOVE = CONFIG.getBoolean(
|
||||
ConfigurationKeys.ENABLE_BRANCH_ASYNC_REMOVE, DEFAULT_ENABLE_BRANCH_ASYNC_REMOVE);
|
||||
/**
|
||||
* The constant CONFIG.
|
||||
*/
|
||||
private static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
|
||||
/**
|
||||
* The instance of DefaultCoordinator
|
||||
*/
|
||||
private static final DefaultCoordinator COORDINATOR = DefaultCoordinator.getInstance();
|
||||
private static final Boolean ENABLE_BRANCH_ASYNC_REMOVE = CONFIG
|
||||
.getBoolean(ConfigurationKeys.ENABLE_BRANCH_ASYNC_REMOVE, DEFAULT_ENABLE_BRANCH_ASYNC_REMOVE);
|
||||
|
||||
private static final boolean DELAY_HANDLE_SESSION = StoreConfig.getSessionMode() != SessionMode.FILE;
|
||||
/**
|
||||
* The instance of DefaultCoordinator
|
||||
*/
|
||||
private static final DefaultCoordinator COORDINATOR = DefaultCoordinator.getInstance();
|
||||
|
||||
private SessionHelper() {
|
||||
}
|
||||
private static final boolean DELAY_HANDLE_SESSION = StoreConfig.getSessionMode() != SessionMode.FILE;
|
||||
|
||||
public static BranchSession newBranchByGlobal(GlobalSession globalSession, BranchType branchType, String resourceId, String lockKeys, String clientId) {
|
||||
return newBranchByGlobal(globalSession, branchType, resourceId, null, lockKeys, clientId);
|
||||
}
|
||||
private SessionHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* New branch by global branch session.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param branchType the branch type
|
||||
* @param resourceId the resource id
|
||||
* @param lockKeys the lock keys
|
||||
* @param clientId the client id
|
||||
* @return the branch session
|
||||
*/
|
||||
public static BranchSession newBranchByGlobal(GlobalSession globalSession, BranchType branchType, String resourceId,
|
||||
String applicationData, String lockKeys, String clientId) {
|
||||
BranchSession branchSession = new BranchSession();
|
||||
public static BranchSession newBranchByGlobal(GlobalSession globalSession, BranchType branchType, String resourceId,
|
||||
String lockKeys, String clientId) {
|
||||
return newBranchByGlobal(globalSession, branchType, resourceId, null, lockKeys, clientId);
|
||||
}
|
||||
|
||||
branchSession.setXid(globalSession.getXid());
|
||||
branchSession.setTransactionId(globalSession.getTransactionId());
|
||||
branchSession.setBranchId(UUIDGenerator.generateUUID());
|
||||
branchSession.setBranchType(branchType);
|
||||
branchSession.setResourceId(resourceId);
|
||||
branchSession.setLockKey(lockKeys);
|
||||
branchSession.setClientId(clientId);
|
||||
branchSession.setApplicationData(applicationData);
|
||||
/**
|
||||
* New branch by global branch session.
|
||||
* @param globalSession the global session
|
||||
* @param branchType the branch type
|
||||
* @param resourceId the resource id
|
||||
* @param lockKeys the lock keys
|
||||
* @param clientId the client id
|
||||
* @return the branch session
|
||||
*/
|
||||
public static BranchSession newBranchByGlobal(GlobalSession globalSession, BranchType branchType, String resourceId,
|
||||
String applicationData, String lockKeys, String clientId) {
|
||||
BranchSession branchSession = new BranchSession();
|
||||
|
||||
return branchSession;
|
||||
}
|
||||
branchSession.setXid(globalSession.getXid());
|
||||
branchSession.setTransactionId(globalSession.getTransactionId());
|
||||
branchSession.setBranchId(UUIDGenerator.generateUUID());
|
||||
branchSession.setBranchType(branchType);
|
||||
branchSession.setResourceId(resourceId);
|
||||
branchSession.setLockKey(lockKeys);
|
||||
branchSession.setClientId(clientId);
|
||||
branchSession.setApplicationData(applicationData);
|
||||
|
||||
/**
|
||||
* New branch
|
||||
*
|
||||
* @param branchType the branch type
|
||||
* @param xid Transaction id.
|
||||
* @param branchId Branch id.
|
||||
* @param resourceId Resource id.
|
||||
* @param applicationData Application data bind with this branch.
|
||||
* @return the branch session
|
||||
*/
|
||||
public static BranchSession newBranch(BranchType branchType, String xid, long branchId, String resourceId, String applicationData) {
|
||||
BranchSession branchSession = new BranchSession();
|
||||
branchSession.setXid(xid);
|
||||
branchSession.setBranchId(branchId);
|
||||
branchSession.setBranchType(branchType);
|
||||
branchSession.setResourceId(resourceId);
|
||||
branchSession.setApplicationData(applicationData);
|
||||
return branchSession;
|
||||
}
|
||||
return branchSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* End committed.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endCommitted(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
|
||||
if (retryGlobal || !DELAY_HANDLE_SESSION) {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
boolean retryBranch = globalSession.getStatus() == GlobalStatus.CommitRetrying;
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Committed);
|
||||
globalSession.end();
|
||||
if (!DELAY_HANDLE_SESSION) {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, false, false);
|
||||
}
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY, true,
|
||||
beginTime, retryBranch);
|
||||
} else {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, false, false);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* New branch
|
||||
* @param branchType the branch type
|
||||
* @param xid Transaction id.
|
||||
* @param branchId Branch id.
|
||||
* @param resourceId Resource id.
|
||||
* @param applicationData Application data bind with this branch.
|
||||
* @return the branch session
|
||||
*/
|
||||
public static BranchSession newBranch(BranchType branchType, String xid, long branchId, String resourceId,
|
||||
String applicationData) {
|
||||
BranchSession branchSession = new BranchSession();
|
||||
branchSession.setXid(xid);
|
||||
branchSession.setBranchId(branchId);
|
||||
branchSession.setBranchType(branchType);
|
||||
branchSession.setResourceId(resourceId);
|
||||
branchSession.setApplicationData(applicationData);
|
||||
return branchSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* End commit failed.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endCommitFailed(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
|
||||
endCommitFailed(globalSession, retryGlobal, false);
|
||||
}
|
||||
/**
|
||||
* End committed.
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endCommitted(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
|
||||
if (retryGlobal || !DELAY_HANDLE_SESSION) {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
boolean retryBranch = globalSession.getStatus() == GlobalStatus.CommitRetrying;
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Committed);
|
||||
globalSession.end();
|
||||
if (!DELAY_HANDLE_SESSION) {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, false, false);
|
||||
}
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, IdConstants.STATUS_VALUE_AFTER_COMMITTED_KEY, true,
|
||||
beginTime, retryBranch);
|
||||
}
|
||||
else {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End commit failed.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @param isRetryTimeout is retry timeout
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endCommitFailed(GlobalSession globalSession, boolean retryGlobal, boolean isRetryTimeout)
|
||||
throws TransactionException {
|
||||
if (isRetryTimeout) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.CommitRetryTimeout);
|
||||
} else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.CommitFailed);
|
||||
}
|
||||
LOGGER.error("The Global session {} has changed the status to {}, need to be handled it manually.",
|
||||
globalSession.getXid(), globalSession.getStatus());
|
||||
/**
|
||||
* End commit failed.
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endCommitFailed(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
|
||||
endCommitFailed(globalSession, retryGlobal, false);
|
||||
}
|
||||
|
||||
globalSession.end();
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, retryGlobal, false);
|
||||
}
|
||||
/**
|
||||
* End commit failed.
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @param isRetryTimeout is retry timeout
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endCommitFailed(GlobalSession globalSession, boolean retryGlobal, boolean isRetryTimeout)
|
||||
throws TransactionException {
|
||||
if (isRetryTimeout) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.CommitRetryTimeout);
|
||||
}
|
||||
else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.CommitFailed);
|
||||
}
|
||||
LOGGER.error("The Global session {} has changed the status to {}, need to be handled it manually.",
|
||||
globalSession.getXid(), globalSession.getStatus());
|
||||
|
||||
/**
|
||||
* End rollbacked.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endRollbacked(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
|
||||
if (retryGlobal || !DELAY_HANDLE_SESSION) {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
boolean timeoutDone = false;
|
||||
GlobalStatus currentStatus = globalSession.getStatus();
|
||||
if (currentStatus == GlobalStatus.TimeoutRollbacking) {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, GlobalStatus.TimeoutRollbacked, false, false);
|
||||
timeoutDone = true;
|
||||
}
|
||||
boolean retryBranch =
|
||||
currentStatus == GlobalStatus.TimeoutRollbackRetrying || currentStatus == GlobalStatus.RollbackRetrying;
|
||||
if (SessionStatusValidator.isTimeoutGlobalStatus(currentStatus)) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.TimeoutRollbacked);
|
||||
} else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Rollbacked);
|
||||
}
|
||||
globalSession.end();
|
||||
if (!DELAY_HANDLE_SESSION && !timeoutDone) {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, false, false);
|
||||
}
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY, true,
|
||||
beginTime, retryBranch);
|
||||
} else {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, GlobalStatus.Rollbacked, false, false);
|
||||
}
|
||||
}
|
||||
globalSession.end();
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, retryGlobal, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* End rollback failed.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endRollbackFailed(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
|
||||
endRollbackFailed(globalSession, retryGlobal, false);
|
||||
}
|
||||
/**
|
||||
* End rollbacked.
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endRollbacked(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
|
||||
if (retryGlobal || !DELAY_HANDLE_SESSION) {
|
||||
long beginTime = System.currentTimeMillis();
|
||||
boolean timeoutDone = false;
|
||||
GlobalStatus currentStatus = globalSession.getStatus();
|
||||
if (currentStatus == GlobalStatus.TimeoutRollbacking) {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, GlobalStatus.TimeoutRollbacked, false, false);
|
||||
timeoutDone = true;
|
||||
}
|
||||
boolean retryBranch = currentStatus == GlobalStatus.TimeoutRollbackRetrying
|
||||
|| currentStatus == GlobalStatus.RollbackRetrying;
|
||||
if (SessionStatusValidator.isTimeoutGlobalStatus(currentStatus)) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.TimeoutRollbacked);
|
||||
}
|
||||
else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Rollbacked);
|
||||
}
|
||||
globalSession.end();
|
||||
if (!DELAY_HANDLE_SESSION && !timeoutDone) {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, false, false);
|
||||
}
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, IdConstants.STATUS_VALUE_AFTER_ROLLBACKED_KEY, true,
|
||||
beginTime, retryBranch);
|
||||
}
|
||||
else {
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, GlobalStatus.Rollbacked, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* End rollback failed.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @param isRetryTimeout is retry timeout
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endRollbackFailed(GlobalSession globalSession, boolean retryGlobal, boolean isRetryTimeout) throws TransactionException {
|
||||
GlobalStatus currentStatus = globalSession.getStatus();
|
||||
if (isRetryTimeout) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.RollbackRetryTimeout);
|
||||
} else if (SessionStatusValidator.isTimeoutGlobalStatus(currentStatus)) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.TimeoutRollbackFailed);
|
||||
} else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.RollbackFailed);
|
||||
}
|
||||
LOGGER.error("The Global session {} has changed the status to {}, need to be handled it manually.", globalSession.getXid(), globalSession.getStatus());
|
||||
globalSession.end();
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, retryGlobal, false);
|
||||
}
|
||||
/**
|
||||
* End rollback failed.
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endRollbackFailed(GlobalSession globalSession, boolean retryGlobal) throws TransactionException {
|
||||
endRollbackFailed(globalSession, retryGlobal, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Foreach global sessions.
|
||||
*
|
||||
* @param sessions the global sessions
|
||||
* @param handler the handler
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static void forEach(Collection<GlobalSession> sessions, GlobalSessionHandler handler) {
|
||||
if (CollectionUtils.isEmpty(sessions)) {
|
||||
return;
|
||||
}
|
||||
sessions.parallelStream().forEach(globalSession -> {
|
||||
try {
|
||||
MDC.put(RootContext.MDC_KEY_XID, globalSession.getXid());
|
||||
handler.handle(globalSession);
|
||||
} catch (Throwable th) {
|
||||
LOGGER.error("handle global session failed: {}", globalSession.getXid(), th);
|
||||
} finally {
|
||||
MDC.remove(RootContext.MDC_KEY_XID);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* End rollback failed.
|
||||
* @param globalSession the global session
|
||||
* @param retryGlobal the retry global
|
||||
* @param isRetryTimeout is retry timeout
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
public static void endRollbackFailed(GlobalSession globalSession, boolean retryGlobal, boolean isRetryTimeout)
|
||||
throws TransactionException {
|
||||
GlobalStatus currentStatus = globalSession.getStatus();
|
||||
if (isRetryTimeout) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.RollbackRetryTimeout);
|
||||
}
|
||||
else if (SessionStatusValidator.isTimeoutGlobalStatus(currentStatus)) {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.TimeoutRollbackFailed);
|
||||
}
|
||||
else {
|
||||
globalSession.changeGlobalStatus(GlobalStatus.RollbackFailed);
|
||||
}
|
||||
LOGGER.error("The Global session {} has changed the status to {}, need to be handled it manually.",
|
||||
globalSession.getXid(), globalSession.getStatus());
|
||||
globalSession.end();
|
||||
MetricsPublisher.postSessionDoneEvent(globalSession, retryGlobal, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Foreach branch sessions.
|
||||
*
|
||||
* @param sessions the branch session
|
||||
* @param handler the handler
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static Boolean forEach(Collection<BranchSession> sessions, BranchSessionHandler handler) throws TransactionException {
|
||||
Boolean result;
|
||||
for (BranchSession branchSession : sessions) {
|
||||
try {
|
||||
MDC.put(RootContext.MDC_KEY_BRANCH_ID, String.valueOf(branchSession.getBranchId()));
|
||||
result = handler.handle(branchSession);
|
||||
if (result == null) {
|
||||
continue;
|
||||
}
|
||||
return result;
|
||||
} finally {
|
||||
MDC.remove(RootContext.MDC_KEY_BRANCH_ID);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Foreach global sessions.
|
||||
* @param sessions the global sessions
|
||||
* @param handler the handler
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static void forEach(Collection<GlobalSession> sessions, GlobalSessionHandler handler) {
|
||||
if (CollectionUtils.isEmpty(sessions)) {
|
||||
return;
|
||||
}
|
||||
sessions.parallelStream().forEach(globalSession -> {
|
||||
try {
|
||||
MDC.put(RootContext.MDC_KEY_XID, globalSession.getXid());
|
||||
handler.handle(globalSession);
|
||||
}
|
||||
catch (Throwable th) {
|
||||
LOGGER.error("handle global session failed: {}", globalSession.getXid(), th);
|
||||
}
|
||||
finally {
|
||||
MDC.remove(RootContext.MDC_KEY_XID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Foreach branch sessions.
|
||||
* @param sessions the branch session
|
||||
* @param handler the handler
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static Boolean forEach(Collection<BranchSession> sessions, BranchSessionHandler handler)
|
||||
throws TransactionException {
|
||||
Boolean result;
|
||||
for (BranchSession branchSession : sessions) {
|
||||
try {
|
||||
MDC.put(RootContext.MDC_KEY_BRANCH_ID, String.valueOf(branchSession.getBranchId()));
|
||||
result = handler.handle(branchSession);
|
||||
if (result == null) {
|
||||
continue;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
finally {
|
||||
MDC.remove(RootContext.MDC_KEY_BRANCH_ID);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* remove branchSession from globalSession
|
||||
* @param globalSession the globalSession
|
||||
* @param branchSession the branchSession
|
||||
* @param isAsync if asynchronous remove
|
||||
*/
|
||||
public static void removeBranch(GlobalSession globalSession, BranchSession branchSession, boolean isAsync)
|
||||
throws TransactionException {
|
||||
if (Objects.equals(Boolean.TRUE, ENABLE_BRANCH_ASYNC_REMOVE) && isAsync) {
|
||||
COORDINATOR.doBranchRemoveAsync(globalSession, branchSession);
|
||||
} else {
|
||||
globalSession.removeBranch(branchSession);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* remove branchSession from globalSession
|
||||
* @param globalSession the globalSession
|
||||
* @param branchSession the branchSession
|
||||
* @param isAsync if asynchronous remove
|
||||
*/
|
||||
public static void removeBranch(GlobalSession globalSession, BranchSession branchSession, boolean isAsync)
|
||||
throws TransactionException {
|
||||
if (Objects.equals(Boolean.TRUE, ENABLE_BRANCH_ASYNC_REMOVE) && isAsync) {
|
||||
COORDINATOR.doBranchRemoveAsync(globalSession, branchSession);
|
||||
}
|
||||
else {
|
||||
globalSession.removeBranch(branchSession);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove branchSession from globalSession
|
||||
* @param globalSession the globalSession
|
||||
* @param isAsync if asynchronous remove
|
||||
*/
|
||||
public static void removeAllBranch(GlobalSession globalSession, boolean isAsync) throws TransactionException {
|
||||
List<BranchSession> branchSessions = globalSession.getSortedBranches();
|
||||
if (branchSessions == null || branchSessions.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (Objects.equals(Boolean.TRUE, ENABLE_BRANCH_ASYNC_REMOVE) && isAsync) {
|
||||
COORDINATOR.doBranchRemoveAllAsync(globalSession);
|
||||
}
|
||||
else {
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
globalSession.removeBranch(branchSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove branchSession from globalSession
|
||||
* @param globalSession the globalSession
|
||||
* @param isAsync if asynchronous remove
|
||||
*/
|
||||
public static void removeAllBranch(GlobalSession globalSession, boolean isAsync)
|
||||
throws TransactionException {
|
||||
List<BranchSession> branchSessions = globalSession.getSortedBranches();
|
||||
if (branchSessions == null || branchSessions.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (Objects.equals(Boolean.TRUE, ENABLE_BRANCH_ASYNC_REMOVE) && isAsync) {
|
||||
COORDINATOR.doBranchRemoveAllAsync(globalSession);
|
||||
} else {
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
globalSession.removeBranch(branchSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+357
-337
@@ -49,377 +49,397 @@ import static io.seata.common.DefaultValues.DEFAULT_DISTRIBUTED_LOCK_EXPIRE_TIME
|
||||
*/
|
||||
public class SessionHolder {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SessionHolder.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SessionHolder.class);
|
||||
|
||||
/**
|
||||
* The constant CONFIG.
|
||||
*/
|
||||
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
/**
|
||||
* The constant ROOT_SESSION_MANAGER_NAME.
|
||||
*/
|
||||
public static final String ROOT_SESSION_MANAGER_NAME = "root.data";
|
||||
/**
|
||||
* The constant ASYNC_COMMITTING_SESSION_MANAGER_NAME.
|
||||
*/
|
||||
public static final String ASYNC_COMMITTING_SESSION_MANAGER_NAME = "async.commit.data";
|
||||
/**
|
||||
* The constant RETRY_COMMITTING_SESSION_MANAGER_NAME.
|
||||
*/
|
||||
public static final String RETRY_COMMITTING_SESSION_MANAGER_NAME = "retry.commit.data";
|
||||
/**
|
||||
* The constant RETRY_ROLLBACKING_SESSION_MANAGER_NAME.
|
||||
*/
|
||||
public static final String RETRY_ROLLBACKING_SESSION_MANAGER_NAME = "retry.rollback.data";
|
||||
/**
|
||||
* The constant CONFIG.
|
||||
*/
|
||||
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
|
||||
/**
|
||||
* The default session store dir
|
||||
*/
|
||||
public static final String DEFAULT_SESSION_STORE_FILE_DIR = "sessionStore";
|
||||
/**
|
||||
* The constant ROOT_SESSION_MANAGER_NAME.
|
||||
*/
|
||||
public static final String ROOT_SESSION_MANAGER_NAME = "root.data";
|
||||
|
||||
/**
|
||||
* The redis distributed lock expire time
|
||||
*/
|
||||
private static long DISTRIBUTED_LOCK_EXPIRE_TIME = CONFIG.getLong(ConfigurationKeys.DISTRIBUTED_LOCK_EXPIRE_TIME, DEFAULT_DISTRIBUTED_LOCK_EXPIRE_TIME);
|
||||
/**
|
||||
* The constant ASYNC_COMMITTING_SESSION_MANAGER_NAME.
|
||||
*/
|
||||
public static final String ASYNC_COMMITTING_SESSION_MANAGER_NAME = "async.commit.data";
|
||||
|
||||
private static SessionManager ROOT_SESSION_MANAGER;
|
||||
private static SessionManager ASYNC_COMMITTING_SESSION_MANAGER;
|
||||
private static SessionManager RETRY_COMMITTING_SESSION_MANAGER;
|
||||
private static SessionManager RETRY_ROLLBACKING_SESSION_MANAGER;
|
||||
/**
|
||||
* The constant RETRY_COMMITTING_SESSION_MANAGER_NAME.
|
||||
*/
|
||||
public static final String RETRY_COMMITTING_SESSION_MANAGER_NAME = "retry.commit.data";
|
||||
|
||||
private static DistributedLocker DISTRIBUTED_LOCKER;
|
||||
/**
|
||||
* The constant RETRY_ROLLBACKING_SESSION_MANAGER_NAME.
|
||||
*/
|
||||
public static final String RETRY_ROLLBACKING_SESSION_MANAGER_NAME = "retry.rollback.data";
|
||||
|
||||
public static void init() {
|
||||
init(null);
|
||||
}
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* @param sessionMode the store mode: file, db, redis
|
||||
* @throws IOException the io exception
|
||||
*/
|
||||
public static void init(SessionMode sessionMode) {
|
||||
if (null == sessionMode) {
|
||||
sessionMode = StoreConfig.getSessionMode();
|
||||
}
|
||||
if (SessionMode.DB.equals(sessionMode)) {
|
||||
ROOT_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.DB.getName());
|
||||
ASYNC_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.DB.getName(),
|
||||
new Object[]{ASYNC_COMMITTING_SESSION_MANAGER_NAME});
|
||||
RETRY_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.DB.getName(),
|
||||
new Object[]{RETRY_COMMITTING_SESSION_MANAGER_NAME});
|
||||
RETRY_ROLLBACKING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.DB.getName(),
|
||||
new Object[]{RETRY_ROLLBACKING_SESSION_MANAGER_NAME});
|
||||
/**
|
||||
* The default session store dir
|
||||
*/
|
||||
public static final String DEFAULT_SESSION_STORE_FILE_DIR = "sessionStore";
|
||||
|
||||
DISTRIBUTED_LOCKER = DistributedLockerFactory.getDistributedLocker(SessionMode.DB.getName());
|
||||
} else if (SessionMode.FILE.equals(sessionMode)) {
|
||||
String sessionStorePath = CONFIG.getConfig(ConfigurationKeys.STORE_FILE_DIR,
|
||||
DEFAULT_SESSION_STORE_FILE_DIR);
|
||||
if (StringUtils.isBlank(sessionStorePath)) {
|
||||
throw new StoreException("the {store.file.dir} is empty.");
|
||||
}
|
||||
ROOT_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.FILE.getName(),
|
||||
new Object[]{ROOT_SESSION_MANAGER_NAME, sessionStorePath});
|
||||
ASYNC_COMMITTING_SESSION_MANAGER = ROOT_SESSION_MANAGER;
|
||||
RETRY_COMMITTING_SESSION_MANAGER = ROOT_SESSION_MANAGER;
|
||||
RETRY_ROLLBACKING_SESSION_MANAGER = ROOT_SESSION_MANAGER;
|
||||
/**
|
||||
* The redis distributed lock expire time
|
||||
*/
|
||||
private static long DISTRIBUTED_LOCK_EXPIRE_TIME = CONFIG.getLong(ConfigurationKeys.DISTRIBUTED_LOCK_EXPIRE_TIME,
|
||||
DEFAULT_DISTRIBUTED_LOCK_EXPIRE_TIME);
|
||||
|
||||
DISTRIBUTED_LOCKER = DistributedLockerFactory.getDistributedLocker(SessionMode.FILE.getName());
|
||||
} else if (SessionMode.REDIS.equals(sessionMode)) {
|
||||
ROOT_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.REDIS.getName());
|
||||
ASYNC_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.REDIS.getName(), new Object[]{ASYNC_COMMITTING_SESSION_MANAGER_NAME});
|
||||
RETRY_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.REDIS.getName(), new Object[]{RETRY_COMMITTING_SESSION_MANAGER_NAME});
|
||||
RETRY_ROLLBACKING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.REDIS.getName(), new Object[]{RETRY_ROLLBACKING_SESSION_MANAGER_NAME});
|
||||
private static SessionManager ROOT_SESSION_MANAGER;
|
||||
|
||||
DISTRIBUTED_LOCKER = DistributedLockerFactory.getDistributedLocker(SessionMode.REDIS.getName());
|
||||
} else {
|
||||
// unknown store
|
||||
throw new IllegalArgumentException("unknown store mode:" + sessionMode.getName());
|
||||
}
|
||||
reload(sessionMode);
|
||||
}
|
||||
private static SessionManager ASYNC_COMMITTING_SESSION_MANAGER;
|
||||
|
||||
//region reload
|
||||
private static SessionManager RETRY_COMMITTING_SESSION_MANAGER;
|
||||
|
||||
/**
|
||||
* Reload.
|
||||
*
|
||||
* @param sessionMode the mode of store
|
||||
*/
|
||||
protected static void reload(SessionMode sessionMode) {
|
||||
private static SessionManager RETRY_ROLLBACKING_SESSION_MANAGER;
|
||||
|
||||
if (ROOT_SESSION_MANAGER instanceof Reloadable) {
|
||||
((Reloadable) ROOT_SESSION_MANAGER).reload();
|
||||
}
|
||||
private static DistributedLocker DISTRIBUTED_LOCKER;
|
||||
|
||||
if (SessionMode.FILE.equals(sessionMode)) {
|
||||
Collection<GlobalSession> allSessions = ROOT_SESSION_MANAGER.allSessions();
|
||||
if (CollectionUtils.isNotEmpty(allSessions)) {
|
||||
for (GlobalSession globalSession : allSessions) {
|
||||
GlobalStatus globalStatus = globalSession.getStatus();
|
||||
switch (globalStatus) {
|
||||
case UnKnown:
|
||||
case Committed:
|
||||
case CommitFailed:
|
||||
case Rollbacked:
|
||||
case RollbackFailed:
|
||||
case TimeoutRollbacked:
|
||||
case TimeoutRollbackFailed:
|
||||
case Finished:
|
||||
removeInErrorState(globalSession);
|
||||
break;
|
||||
case AsyncCommitting:
|
||||
queueToAsyncCommitting(globalSession);
|
||||
break;
|
||||
case Committing:
|
||||
case CommitRetrying:
|
||||
queueToRetryCommit(globalSession);
|
||||
break;
|
||||
default: {
|
||||
lockBranchSessions(globalSession.getSortedBranches());
|
||||
switch (globalStatus) {
|
||||
case Rollbacking:
|
||||
case RollbackRetrying:
|
||||
case TimeoutRollbacking:
|
||||
case TimeoutRollbackRetrying:
|
||||
globalSession.getBranchSessions().parallelStream()
|
||||
.forEach(branchSession -> branchSession.setLockStatus(LockStatus.Rollbacking));
|
||||
queueToRetryRollback(globalSession);
|
||||
break;
|
||||
case Begin:
|
||||
globalSession.setActive(true);
|
||||
break;
|
||||
default:
|
||||
LOGGER.error("Could not handle the global session, xid: {}", globalSession.getXid());
|
||||
throw new ShouldNeverHappenException("NOT properly handled " + globalStatus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Redis, db and so on
|
||||
CompletableFuture.runAsync(() -> {
|
||||
SessionCondition searchCondition = new SessionCondition(GlobalStatus.UnKnown, GlobalStatus.Committed,
|
||||
GlobalStatus.Rollbacked, GlobalStatus.TimeoutRollbacked, GlobalStatus.Finished);
|
||||
searchCondition.setLazyLoadBranch(true);
|
||||
public static void init() {
|
||||
init(null);
|
||||
}
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
List<GlobalSession> errorStatusGlobalSessions = ROOT_SESSION_MANAGER.findGlobalSessions(searchCondition);
|
||||
while (!CollectionUtils.isEmpty(errorStatusGlobalSessions)) {
|
||||
for (GlobalSession errorStatusGlobalSession : errorStatusGlobalSessions) {
|
||||
if (errorStatusGlobalSession.getBeginTime() >= now) {
|
||||
// Exit when the global transaction begin after the instance started
|
||||
return;
|
||||
}
|
||||
/**
|
||||
* Init.
|
||||
* @param sessionMode the store mode: file, db, redis
|
||||
* @throws IOException the io exception
|
||||
*/
|
||||
public static void init(SessionMode sessionMode) {
|
||||
if (null == sessionMode) {
|
||||
sessionMode = StoreConfig.getSessionMode();
|
||||
}
|
||||
if (SessionMode.DB.equals(sessionMode)) {
|
||||
ROOT_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.DB.getName());
|
||||
ASYNC_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.DB.getName(), new Object[] { ASYNC_COMMITTING_SESSION_MANAGER_NAME });
|
||||
RETRY_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.DB.getName(), new Object[] { RETRY_COMMITTING_SESSION_MANAGER_NAME });
|
||||
RETRY_ROLLBACKING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.DB.getName(), new Object[] { RETRY_ROLLBACKING_SESSION_MANAGER_NAME });
|
||||
|
||||
removeInErrorState(errorStatusGlobalSession);
|
||||
}
|
||||
DISTRIBUTED_LOCKER = DistributedLockerFactory.getDistributedLocker(SessionMode.DB.getName());
|
||||
}
|
||||
else if (SessionMode.FILE.equals(sessionMode)) {
|
||||
String sessionStorePath = CONFIG.getConfig(ConfigurationKeys.STORE_FILE_DIR,
|
||||
DEFAULT_SESSION_STORE_FILE_DIR);
|
||||
if (StringUtils.isBlank(sessionStorePath)) {
|
||||
throw new StoreException("the {store.file.dir} is empty.");
|
||||
}
|
||||
ROOT_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.FILE.getName(),
|
||||
new Object[] { ROOT_SESSION_MANAGER_NAME, sessionStorePath });
|
||||
ASYNC_COMMITTING_SESSION_MANAGER = ROOT_SESSION_MANAGER;
|
||||
RETRY_COMMITTING_SESSION_MANAGER = ROOT_SESSION_MANAGER;
|
||||
RETRY_ROLLBACKING_SESSION_MANAGER = ROOT_SESSION_MANAGER;
|
||||
|
||||
// Load the next part
|
||||
errorStatusGlobalSessions = ROOT_SESSION_MANAGER.findGlobalSessions(searchCondition);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
DISTRIBUTED_LOCKER = DistributedLockerFactory.getDistributedLocker(SessionMode.FILE.getName());
|
||||
}
|
||||
else if (SessionMode.REDIS.equals(sessionMode)) {
|
||||
ROOT_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class, SessionMode.REDIS.getName());
|
||||
ASYNC_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.REDIS.getName(), new Object[] { ASYNC_COMMITTING_SESSION_MANAGER_NAME });
|
||||
RETRY_COMMITTING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.REDIS.getName(), new Object[] { RETRY_COMMITTING_SESSION_MANAGER_NAME });
|
||||
RETRY_ROLLBACKING_SESSION_MANAGER = EnhancedServiceLoader.load(SessionManager.class,
|
||||
SessionMode.REDIS.getName(), new Object[] { RETRY_ROLLBACKING_SESSION_MANAGER_NAME });
|
||||
|
||||
private static void removeInErrorState(GlobalSession globalSession) {
|
||||
try {
|
||||
LOGGER.warn("The global session should NOT be {}, remove it. xid = {}", globalSession.getStatus(), globalSession.getXid());
|
||||
ROOT_SESSION_MANAGER.removeGlobalSession(globalSession);
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Remove global session succeed, xid = {}, status = {}", globalSession.getXid(), globalSession.getStatus());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Remove global session failed, xid = {}, status = {}", globalSession.getXid(), globalSession.getStatus(), e);
|
||||
}
|
||||
}
|
||||
DISTRIBUTED_LOCKER = DistributedLockerFactory.getDistributedLocker(SessionMode.REDIS.getName());
|
||||
}
|
||||
else {
|
||||
// unknown store
|
||||
throw new IllegalArgumentException("unknown store mode:" + sessionMode.getName());
|
||||
}
|
||||
reload(sessionMode);
|
||||
}
|
||||
|
||||
private static void queueToAsyncCommitting(GlobalSession globalSession) {
|
||||
try {
|
||||
globalSession.addSessionLifecycleListener(getAsyncCommittingSessionManager());
|
||||
getAsyncCommittingSessionManager().addGlobalSession(globalSession);
|
||||
} catch (TransactionException e) {
|
||||
throw new ShouldNeverHappenException(e);
|
||||
}
|
||||
}
|
||||
// region reload
|
||||
|
||||
private static void lockBranchSessions(List<BranchSession> branchSessions) {
|
||||
branchSessions.forEach(branchSession -> {
|
||||
try {
|
||||
branchSession.lock();
|
||||
} catch (TransactionException e) {
|
||||
throw new ShouldNeverHappenException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Reload.
|
||||
* @param sessionMode the mode of store
|
||||
*/
|
||||
protected static void reload(SessionMode sessionMode) {
|
||||
|
||||
private static void queueToRetryCommit(GlobalSession globalSession) {
|
||||
try {
|
||||
globalSession.addSessionLifecycleListener(getRetryCommittingSessionManager());
|
||||
getRetryCommittingSessionManager().addGlobalSession(globalSession);
|
||||
} catch (TransactionException e) {
|
||||
throw new ShouldNeverHappenException(e);
|
||||
}
|
||||
}
|
||||
if (ROOT_SESSION_MANAGER instanceof Reloadable) {
|
||||
((Reloadable) ROOT_SESSION_MANAGER).reload();
|
||||
}
|
||||
|
||||
private static void queueToRetryRollback(GlobalSession globalSession) {
|
||||
try {
|
||||
globalSession.addSessionLifecycleListener(getRetryRollbackingSessionManager());
|
||||
getRetryRollbackingSessionManager().addGlobalSession(globalSession);
|
||||
} catch (TransactionException e) {
|
||||
throw new ShouldNeverHappenException(e);
|
||||
}
|
||||
}
|
||||
if (SessionMode.FILE.equals(sessionMode)) {
|
||||
Collection<GlobalSession> allSessions = ROOT_SESSION_MANAGER.allSessions();
|
||||
if (CollectionUtils.isNotEmpty(allSessions)) {
|
||||
for (GlobalSession globalSession : allSessions) {
|
||||
GlobalStatus globalStatus = globalSession.getStatus();
|
||||
switch (globalStatus) {
|
||||
case UnKnown:
|
||||
case Committed:
|
||||
case CommitFailed:
|
||||
case Rollbacked:
|
||||
case RollbackFailed:
|
||||
case TimeoutRollbacked:
|
||||
case TimeoutRollbackFailed:
|
||||
case Finished:
|
||||
removeInErrorState(globalSession);
|
||||
break;
|
||||
case AsyncCommitting:
|
||||
queueToAsyncCommitting(globalSession);
|
||||
break;
|
||||
case Committing:
|
||||
case CommitRetrying:
|
||||
queueToRetryCommit(globalSession);
|
||||
break;
|
||||
default: {
|
||||
lockBranchSessions(globalSession.getSortedBranches());
|
||||
switch (globalStatus) {
|
||||
case Rollbacking:
|
||||
case RollbackRetrying:
|
||||
case TimeoutRollbacking:
|
||||
case TimeoutRollbackRetrying:
|
||||
globalSession.getBranchSessions().parallelStream().forEach(
|
||||
branchSession -> branchSession.setLockStatus(LockStatus.Rollbacking));
|
||||
queueToRetryRollback(globalSession);
|
||||
break;
|
||||
case Begin:
|
||||
globalSession.setActive(true);
|
||||
break;
|
||||
default:
|
||||
LOGGER.error("Could not handle the global session, xid: {}",
|
||||
globalSession.getXid());
|
||||
throw new ShouldNeverHappenException("NOT properly handled " + globalStatus);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Redis, db and so on
|
||||
CompletableFuture.runAsync(() -> {
|
||||
SessionCondition searchCondition = new SessionCondition(GlobalStatus.UnKnown, GlobalStatus.Committed,
|
||||
GlobalStatus.Rollbacked, GlobalStatus.TimeoutRollbacked, GlobalStatus.Finished);
|
||||
searchCondition.setLazyLoadBranch(true);
|
||||
|
||||
//endregion
|
||||
long now = System.currentTimeMillis();
|
||||
List<GlobalSession> errorStatusGlobalSessions = ROOT_SESSION_MANAGER
|
||||
.findGlobalSessions(searchCondition);
|
||||
while (!CollectionUtils.isEmpty(errorStatusGlobalSessions)) {
|
||||
for (GlobalSession errorStatusGlobalSession : errorStatusGlobalSessions) {
|
||||
if (errorStatusGlobalSession.getBeginTime() >= now) {
|
||||
// Exit when the global transaction begin after the instance
|
||||
// started
|
||||
return;
|
||||
}
|
||||
|
||||
//region get session manager
|
||||
removeInErrorState(errorStatusGlobalSession);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets root session manager.
|
||||
*
|
||||
* @return the root session manager
|
||||
*/
|
||||
public static SessionManager getRootSessionManager() {
|
||||
if (ROOT_SESSION_MANAGER == null) {
|
||||
throw new ShouldNeverHappenException("SessionManager is NOT init!");
|
||||
}
|
||||
return ROOT_SESSION_MANAGER;
|
||||
}
|
||||
// Load the next part
|
||||
errorStatusGlobalSessions = ROOT_SESSION_MANAGER.findGlobalSessions(searchCondition);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets async committing session manager.
|
||||
*
|
||||
* @return the async committing session manager
|
||||
*/
|
||||
@Deprecated
|
||||
public static SessionManager getAsyncCommittingSessionManager() {
|
||||
if (ASYNC_COMMITTING_SESSION_MANAGER == null) {
|
||||
throw new ShouldNeverHappenException("SessionManager is NOT init!");
|
||||
}
|
||||
return ASYNC_COMMITTING_SESSION_MANAGER;
|
||||
}
|
||||
private static void removeInErrorState(GlobalSession globalSession) {
|
||||
try {
|
||||
LOGGER.warn("The global session should NOT be {}, remove it. xid = {}", globalSession.getStatus(),
|
||||
globalSession.getXid());
|
||||
ROOT_SESSION_MANAGER.removeGlobalSession(globalSession);
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Remove global session succeed, xid = {}, status = {}", globalSession.getXid(),
|
||||
globalSession.getStatus());
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.error("Remove global session failed, xid = {}, status = {}", globalSession.getXid(),
|
||||
globalSession.getStatus(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets retry committing session manager.
|
||||
*
|
||||
* @return the retry committing session manager
|
||||
*/
|
||||
@Deprecated
|
||||
public static SessionManager getRetryCommittingSessionManager() {
|
||||
if (RETRY_COMMITTING_SESSION_MANAGER == null) {
|
||||
throw new ShouldNeverHappenException("SessionManager is NOT init!");
|
||||
}
|
||||
return RETRY_COMMITTING_SESSION_MANAGER;
|
||||
}
|
||||
private static void queueToAsyncCommitting(GlobalSession globalSession) {
|
||||
try {
|
||||
globalSession.addSessionLifecycleListener(getAsyncCommittingSessionManager());
|
||||
getAsyncCommittingSessionManager().addGlobalSession(globalSession);
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
throw new ShouldNeverHappenException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets retry rollbacking session manager.
|
||||
*
|
||||
* @return the retry rollbacking session manager
|
||||
*/
|
||||
@Deprecated
|
||||
public static SessionManager getRetryRollbackingSessionManager() {
|
||||
if (RETRY_ROLLBACKING_SESSION_MANAGER == null) {
|
||||
throw new ShouldNeverHappenException("SessionManager is NOT init!");
|
||||
}
|
||||
return RETRY_ROLLBACKING_SESSION_MANAGER;
|
||||
}
|
||||
private static void lockBranchSessions(List<BranchSession> branchSessions) {
|
||||
branchSessions.forEach(branchSession -> {
|
||||
try {
|
||||
branchSession.lock();
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
throw new ShouldNeverHappenException(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//endregion
|
||||
private static void queueToRetryCommit(GlobalSession globalSession) {
|
||||
try {
|
||||
globalSession.addSessionLifecycleListener(getRetryCommittingSessionManager());
|
||||
getRetryCommittingSessionManager().addGlobalSession(globalSession);
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
throw new ShouldNeverHappenException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find global session.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @return the global session
|
||||
*/
|
||||
public static GlobalSession findGlobalSession(String xid) {
|
||||
return findGlobalSession(xid, true);
|
||||
}
|
||||
private static void queueToRetryRollback(GlobalSession globalSession) {
|
||||
try {
|
||||
globalSession.addSessionLifecycleListener(getRetryRollbackingSessionManager());
|
||||
getRetryRollbackingSessionManager().addGlobalSession(globalSession);
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
throw new ShouldNeverHappenException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find global session.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
public static GlobalSession findGlobalSession(String xid, boolean withBranchSessions) {
|
||||
return getRootSessionManager().findGlobalSession(xid, withBranchSessions);
|
||||
}
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* lock and execute
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param lockCallable the lock Callable
|
||||
* @return the value
|
||||
*/
|
||||
public static <T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException {
|
||||
return getRootSessionManager().lockAndExecute(globalSession, lockCallable);
|
||||
}
|
||||
// region get session manager
|
||||
|
||||
/**
|
||||
* acquire lock
|
||||
*
|
||||
* @param lockKey the lock key, should be distinct for each lock
|
||||
* @return the boolean
|
||||
*/
|
||||
public static boolean acquireDistributedLock(String lockKey) {
|
||||
return DISTRIBUTED_LOCKER.acquireLock(new DistributedLockDO(lockKey, XID.getIpAddressAndPort(), DISTRIBUTED_LOCK_EXPIRE_TIME));
|
||||
}
|
||||
/**
|
||||
* Gets root session manager.
|
||||
* @return the root session manager
|
||||
*/
|
||||
public static SessionManager getRootSessionManager() {
|
||||
if (ROOT_SESSION_MANAGER == null) {
|
||||
throw new ShouldNeverHappenException("SessionManager is NOT init!");
|
||||
}
|
||||
return ROOT_SESSION_MANAGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* release lock
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
public static boolean releaseDistributedLock(String lockKey) {
|
||||
return DISTRIBUTED_LOCKER.releaseLock(new DistributedLockDO(lockKey, XID.getIpAddressAndPort(), DISTRIBUTED_LOCK_EXPIRE_TIME));
|
||||
}
|
||||
/**
|
||||
* Gets async committing session manager.
|
||||
* @return the async committing session manager
|
||||
*/
|
||||
@Deprecated
|
||||
public static SessionManager getAsyncCommittingSessionManager() {
|
||||
if (ASYNC_COMMITTING_SESSION_MANAGER == null) {
|
||||
throw new ShouldNeverHappenException("SessionManager is NOT init!");
|
||||
}
|
||||
return ASYNC_COMMITTING_SESSION_MANAGER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the function after get the distribute lock
|
||||
*
|
||||
* @param key the distribute lock key
|
||||
* @param func the function to be call
|
||||
* @return whether the func be call
|
||||
*/
|
||||
public static boolean distributedLockAndExecute(String key, NoArgsFunc func) {
|
||||
boolean lock = false;
|
||||
try {
|
||||
if (lock = acquireDistributedLock(key)) {
|
||||
func.call();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.info("Exception running function with key = {}", key, e);
|
||||
} finally {
|
||||
if (lock) {
|
||||
try {
|
||||
SessionHolder.releaseDistributedLock(key);
|
||||
} catch (Exception ex) {
|
||||
LOGGER.warn("release distribute lock failure, message = {}", ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
/**
|
||||
* Gets retry committing session manager.
|
||||
* @return the retry committing session manager
|
||||
*/
|
||||
@Deprecated
|
||||
public static SessionManager getRetryCommittingSessionManager() {
|
||||
if (RETRY_COMMITTING_SESSION_MANAGER == null) {
|
||||
throw new ShouldNeverHappenException("SessionManager is NOT init!");
|
||||
}
|
||||
return RETRY_COMMITTING_SESSION_MANAGER;
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if (ROOT_SESSION_MANAGER != null) {
|
||||
ROOT_SESSION_MANAGER.destroy();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Gets retry rollbacking session manager.
|
||||
* @return the retry rollbacking session manager
|
||||
*/
|
||||
@Deprecated
|
||||
public static SessionManager getRetryRollbackingSessionManager() {
|
||||
if (RETRY_ROLLBACKING_SESSION_MANAGER == null) {
|
||||
throw new ShouldNeverHappenException("SessionManager is NOT init!");
|
||||
}
|
||||
return RETRY_ROLLBACKING_SESSION_MANAGER;
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* Find global session.
|
||||
* @param xid the xid
|
||||
* @return the global session
|
||||
*/
|
||||
public static GlobalSession findGlobalSession(String xid) {
|
||||
return findGlobalSession(xid, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find global session.
|
||||
* @param xid the xid
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
public static GlobalSession findGlobalSession(String xid, boolean withBranchSessions) {
|
||||
return getRootSessionManager().findGlobalSession(xid, withBranchSessions);
|
||||
}
|
||||
|
||||
/**
|
||||
* lock and execute
|
||||
* @param globalSession the global session
|
||||
* @param lockCallable the lock Callable
|
||||
* @return the value
|
||||
*/
|
||||
public static <T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException {
|
||||
return getRootSessionManager().lockAndExecute(globalSession, lockCallable);
|
||||
}
|
||||
|
||||
/**
|
||||
* acquire lock
|
||||
* @param lockKey the lock key, should be distinct for each lock
|
||||
* @return the boolean
|
||||
*/
|
||||
public static boolean acquireDistributedLock(String lockKey) {
|
||||
return DISTRIBUTED_LOCKER
|
||||
.acquireLock(new DistributedLockDO(lockKey, XID.getIpAddressAndPort(), DISTRIBUTED_LOCK_EXPIRE_TIME));
|
||||
}
|
||||
|
||||
/**
|
||||
* release lock
|
||||
* @return the boolean
|
||||
*/
|
||||
public static boolean releaseDistributedLock(String lockKey) {
|
||||
return DISTRIBUTED_LOCKER
|
||||
.releaseLock(new DistributedLockDO(lockKey, XID.getIpAddressAndPort(), DISTRIBUTED_LOCK_EXPIRE_TIME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the function after get the distribute lock
|
||||
* @param key the distribute lock key
|
||||
* @param func the function to be call
|
||||
* @return whether the func be call
|
||||
*/
|
||||
public static boolean distributedLockAndExecute(String key, NoArgsFunc func) {
|
||||
boolean lock = false;
|
||||
try {
|
||||
if (lock = acquireDistributedLock(key)) {
|
||||
func.call();
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.info("Exception running function with key = {}", key, e);
|
||||
}
|
||||
finally {
|
||||
if (lock) {
|
||||
try {
|
||||
SessionHolder.releaseDistributedLock(key);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
LOGGER.warn("release distribute lock failure, message = {}", ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return lock;
|
||||
}
|
||||
|
||||
public static void destroy() {
|
||||
if (ROOT_SESSION_MANAGER != null) {
|
||||
ROOT_SESSION_MANAGER.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface NoArgsFunc {
|
||||
|
||||
void call();
|
||||
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface NoArgsFunc {
|
||||
void call();
|
||||
}
|
||||
}
|
||||
+46
-53
@@ -26,64 +26,57 @@ import io.seata.core.model.GlobalStatus;
|
||||
*/
|
||||
public interface SessionLifecycle {
|
||||
|
||||
/**
|
||||
* Begin.
|
||||
*
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void begin() throws TransactionException;
|
||||
/**
|
||||
* Begin.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void begin() throws TransactionException;
|
||||
|
||||
/**
|
||||
* Change status.
|
||||
*
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void changeGlobalStatus(GlobalStatus status) throws TransactionException;
|
||||
/**
|
||||
* Change status.
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void changeGlobalStatus(GlobalStatus status) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Change branch status.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void changeBranchStatus(BranchSession branchSession, BranchStatus status) throws TransactionException;
|
||||
/**
|
||||
* Change branch status.
|
||||
* @param branchSession the branch session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void changeBranchStatus(BranchSession branchSession, BranchStatus status) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Add branch.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void addBranch(BranchSession branchSession) throws TransactionException;
|
||||
/**
|
||||
* Add branch.
|
||||
* @param branchSession the branch session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void addBranch(BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Remove branch.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void removeBranch(BranchSession branchSession) throws TransactionException;
|
||||
/**
|
||||
* Remove branch.
|
||||
* @param branchSession the branch session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void removeBranch(BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Is active boolean.
|
||||
*
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean isActive();
|
||||
/**
|
||||
* Is active boolean.
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean isActive();
|
||||
|
||||
/**
|
||||
* Close.
|
||||
*
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void close() throws TransactionException;
|
||||
/**
|
||||
* Close.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void close() throws TransactionException;
|
||||
|
||||
/**
|
||||
* end.
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void end() throws TransactionException;
|
||||
|
||||
/**
|
||||
* end.
|
||||
*
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void end() throws TransactionException;
|
||||
}
|
||||
+55
-62
@@ -26,73 +26,66 @@ import io.seata.core.model.GlobalStatus;
|
||||
*/
|
||||
public interface SessionLifecycleListener {
|
||||
|
||||
/**
|
||||
* On begin.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onBegin(GlobalSession globalSession) throws TransactionException;
|
||||
/**
|
||||
* On begin.
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onBegin(GlobalSession globalSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* On status change.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onStatusChange(GlobalSession globalSession, GlobalStatus status) throws TransactionException;
|
||||
/**
|
||||
* On status change.
|
||||
* @param globalSession the global session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onStatusChange(GlobalSession globalSession, GlobalStatus status) throws TransactionException;
|
||||
|
||||
/**
|
||||
* On branch status change.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onBranchStatusChange(GlobalSession globalSession, BranchSession branchSession, BranchStatus status)
|
||||
throws TransactionException;
|
||||
/**
|
||||
* On branch status change.
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onBranchStatusChange(GlobalSession globalSession, BranchSession branchSession, BranchStatus status)
|
||||
throws TransactionException;
|
||||
|
||||
/**
|
||||
* On add branch.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onAddBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
/**
|
||||
* On add branch.
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onAddBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* On remove branch.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onRemoveBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
/**
|
||||
* On remove branch.
|
||||
* @param globalSession the global session
|
||||
* @param branchSession the branch session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onRemoveBranch(GlobalSession globalSession, BranchSession branchSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* On close.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onClose(GlobalSession globalSession) throws TransactionException;
|
||||
/**
|
||||
* On close.
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onClose(GlobalSession globalSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* On end.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onSuccessEnd(GlobalSession globalSession) throws TransactionException;
|
||||
/**
|
||||
* On end.
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onSuccessEnd(GlobalSession globalSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* On fail end.
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onFailEnd(GlobalSession globalSession) throws TransactionException;
|
||||
|
||||
/**
|
||||
* On fail end.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void onFailEnd(GlobalSession globalSession) throws TransactionException;
|
||||
}
|
||||
+74
-84
@@ -30,98 +30,88 @@ import java.util.List;
|
||||
*/
|
||||
public interface SessionManager extends SessionLifecycleListener, Disposable {
|
||||
|
||||
/**
|
||||
* Add global session.
|
||||
*
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void addGlobalSession(GlobalSession session) throws TransactionException;
|
||||
/**
|
||||
* Add global session.
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void addGlobalSession(GlobalSession session) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Find global session global session.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @return the global session
|
||||
*/
|
||||
GlobalSession findGlobalSession(String xid) ;
|
||||
/**
|
||||
* Find global session global session.
|
||||
* @param xid the xid
|
||||
* @return the global session
|
||||
*/
|
||||
GlobalSession findGlobalSession(String xid);
|
||||
|
||||
/**
|
||||
* Find global session global session.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
GlobalSession findGlobalSession(String xid, boolean withBranchSessions);
|
||||
/**
|
||||
* Find global session global session.
|
||||
* @param xid the xid
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
GlobalSession findGlobalSession(String xid, boolean withBranchSessions);
|
||||
|
||||
/**
|
||||
* Update global session status.
|
||||
*
|
||||
* @param session the session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException;
|
||||
/**
|
||||
* Update global session status.
|
||||
* @param session the session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Remove global session.
|
||||
*
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void removeGlobalSession(GlobalSession session) throws TransactionException;
|
||||
/**
|
||||
* Remove global session.
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void removeGlobalSession(GlobalSession session) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Add branch session.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void addBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException;
|
||||
/**
|
||||
* Add branch session.
|
||||
* @param globalSession the global session
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void addBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Update branch session status.
|
||||
*
|
||||
* @param session the session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void updateBranchSessionStatus(BranchSession session, BranchStatus status) throws TransactionException;
|
||||
/**
|
||||
* Update branch session status.
|
||||
* @param session the session
|
||||
* @param status the status
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void updateBranchSessionStatus(BranchSession session, BranchStatus status) throws TransactionException;
|
||||
|
||||
/**
|
||||
* Remove branch session.
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void removeBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException;
|
||||
/**
|
||||
* Remove branch session.
|
||||
* @param globalSession the global session
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
void removeBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException;
|
||||
|
||||
/**
|
||||
* All sessions collection.
|
||||
*
|
||||
* @return the collection
|
||||
*/
|
||||
Collection<GlobalSession> allSessions();
|
||||
/**
|
||||
* All sessions collection.
|
||||
* @return the collection
|
||||
*/
|
||||
Collection<GlobalSession> allSessions();
|
||||
|
||||
/**
|
||||
* Find global sessions list.
|
||||
*
|
||||
* @param condition the condition
|
||||
* @return the list
|
||||
*/
|
||||
List<GlobalSession> findGlobalSessions(SessionCondition condition);
|
||||
/**
|
||||
* Find global sessions list.
|
||||
* @param condition the condition
|
||||
* @return the list
|
||||
*/
|
||||
List<GlobalSession> findGlobalSessions(SessionCondition condition);
|
||||
|
||||
/**
|
||||
* lock and execute
|
||||
* @param globalSession the global session
|
||||
* @param lockCallable the lock Callable
|
||||
* @return the value
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
<T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException;
|
||||
|
||||
/**
|
||||
* lock and execute
|
||||
*
|
||||
* @param globalSession the global session
|
||||
* @param lockCallable the lock Callable
|
||||
* @return the value
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
<T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException;
|
||||
}
|
||||
+47
-57
@@ -24,64 +24,54 @@ import io.seata.core.model.GlobalStatus;
|
||||
*/
|
||||
public class SessionStatusValidator {
|
||||
|
||||
/**
|
||||
* is timeout global status
|
||||
*
|
||||
* @param status the global session
|
||||
*/
|
||||
public static boolean isTimeoutGlobalStatus(GlobalStatus status) {
|
||||
return status == GlobalStatus.TimeoutRollbacked
|
||||
|| status == GlobalStatus.TimeoutRollbackFailed
|
||||
|| status == GlobalStatus.TimeoutRollbacking
|
||||
|| status == GlobalStatus.TimeoutRollbackRetrying;
|
||||
}
|
||||
/**
|
||||
* is timeout global status
|
||||
* @param status the global session
|
||||
*/
|
||||
public static boolean isTimeoutGlobalStatus(GlobalStatus status) {
|
||||
return status == GlobalStatus.TimeoutRollbacked || status == GlobalStatus.TimeoutRollbackFailed
|
||||
|| status == GlobalStatus.TimeoutRollbacking || status == GlobalStatus.TimeoutRollbackRetrying;
|
||||
}
|
||||
|
||||
/**
|
||||
* is rollback global status
|
||||
*
|
||||
* @param status the global session
|
||||
*/
|
||||
public static boolean isRollbackGlobalStatus(GlobalStatus status) {
|
||||
return status == GlobalStatus.Rollbacking
|
||||
|| status == GlobalStatus.RollbackRetrying
|
||||
|| status == GlobalStatus.Rollbacked
|
||||
|| status == GlobalStatus.RollbackFailed
|
||||
|| status == GlobalStatus.RollbackRetryTimeout;
|
||||
}
|
||||
/**
|
||||
* is rollback global status
|
||||
* @param status the global session
|
||||
*/
|
||||
public static boolean isRollbackGlobalStatus(GlobalStatus status) {
|
||||
return status == GlobalStatus.Rollbacking || status == GlobalStatus.RollbackRetrying
|
||||
|| status == GlobalStatus.Rollbacked || status == GlobalStatus.RollbackFailed
|
||||
|| status == GlobalStatus.RollbackRetryTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* is commit global status
|
||||
*
|
||||
* @param status the global session
|
||||
*/
|
||||
public static boolean isCommitGlobalStatus(GlobalStatus status) {
|
||||
return status == GlobalStatus.Committing
|
||||
|| status == GlobalStatus.AsyncCommitting
|
||||
|| status == GlobalStatus.CommitRetrying
|
||||
|| status == GlobalStatus.Committed
|
||||
|| status == GlobalStatus.CommitFailed
|
||||
|| status == GlobalStatus.CommitRetryTimeout;
|
||||
}
|
||||
/**
|
||||
* is commit global status
|
||||
* @param status the global session
|
||||
*/
|
||||
public static boolean isCommitGlobalStatus(GlobalStatus status) {
|
||||
return status == GlobalStatus.Committing || status == GlobalStatus.AsyncCommitting
|
||||
|| status == GlobalStatus.CommitRetrying || status == GlobalStatus.Committed
|
||||
|| status == GlobalStatus.CommitFailed || status == GlobalStatus.CommitRetryTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* check the relation of before status and after status
|
||||
* @param before the global session
|
||||
* @param after the global session
|
||||
*/
|
||||
public static boolean validateUpdateStatus(GlobalStatus before, GlobalStatus after) {
|
||||
if (isTimeoutGlobalStatus(before) && isCommitGlobalStatus(after)) {
|
||||
return false;
|
||||
}
|
||||
if (isCommitGlobalStatus(before) && isTimeoutGlobalStatus(after)) {
|
||||
return false;
|
||||
}
|
||||
if (isRollbackGlobalStatus(before) && isCommitGlobalStatus(after)) {
|
||||
return false;
|
||||
}
|
||||
if (isCommitGlobalStatus(before) && isRollbackGlobalStatus(after)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* check the relation of before status and after status
|
||||
*
|
||||
* @param before the global session
|
||||
* @param after the global session
|
||||
*/
|
||||
public static boolean validateUpdateStatus(GlobalStatus before, GlobalStatus after) {
|
||||
if (isTimeoutGlobalStatus(before) && isCommitGlobalStatus(after)) {
|
||||
return false;
|
||||
}
|
||||
if (isCommitGlobalStatus(before) && isTimeoutGlobalStatus(after)) {
|
||||
return false;
|
||||
}
|
||||
if (isRollbackGlobalStatus(before) && isCommitGlobalStatus(after)) {
|
||||
return false;
|
||||
}
|
||||
if (isCommitGlobalStatus(before) && isRollbackGlobalStatus(after)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+129
-148
@@ -39,169 +39,150 @@ import java.util.*;
|
||||
*/
|
||||
public class SessionConverter {
|
||||
|
||||
public static GlobalSession convertGlobalSession(GlobalTransactionDO globalTransactionDO, boolean lazyLoadBranch) {
|
||||
if (globalTransactionDO == null) {
|
||||
return null;
|
||||
}
|
||||
GlobalSession session = new GlobalSession(globalTransactionDO.getApplicationId(),
|
||||
globalTransactionDO.getTransactionServiceGroup(),
|
||||
globalTransactionDO.getTransactionName(),
|
||||
globalTransactionDO.getTimeout(), lazyLoadBranch);
|
||||
session.setXid(globalTransactionDO.getXid());
|
||||
session.setTransactionId(globalTransactionDO.getTransactionId());
|
||||
session.setStatus(GlobalStatus.get(globalTransactionDO.getStatus()));
|
||||
session.setApplicationData(globalTransactionDO.getApplicationData());
|
||||
session.setBeginTime(globalTransactionDO.getBeginTime());
|
||||
return session;
|
||||
}
|
||||
public static GlobalSession convertGlobalSession(GlobalTransactionDO globalTransactionDO, boolean lazyLoadBranch) {
|
||||
if (globalTransactionDO == null) {
|
||||
return null;
|
||||
}
|
||||
GlobalSession session = new GlobalSession(globalTransactionDO.getApplicationId(),
|
||||
globalTransactionDO.getTransactionServiceGroup(), globalTransactionDO.getTransactionName(),
|
||||
globalTransactionDO.getTimeout(), lazyLoadBranch);
|
||||
session.setXid(globalTransactionDO.getXid());
|
||||
session.setTransactionId(globalTransactionDO.getTransactionId());
|
||||
session.setStatus(GlobalStatus.get(globalTransactionDO.getStatus()));
|
||||
session.setApplicationData(globalTransactionDO.getApplicationData());
|
||||
session.setBeginTime(globalTransactionDO.getBeginTime());
|
||||
return session;
|
||||
}
|
||||
|
||||
public static GlobalSession convertGlobalSession(GlobalTransactionDO globalTransactionDO) {
|
||||
return convertGlobalSession(globalTransactionDO, false);
|
||||
}
|
||||
public static GlobalSession convertGlobalSession(GlobalTransactionDO globalTransactionDO) {
|
||||
return convertGlobalSession(globalTransactionDO, false);
|
||||
}
|
||||
|
||||
public static BranchSession convertBranchSession(BranchTransactionDO branchTransactionDO) {
|
||||
if (branchTransactionDO == null) {
|
||||
return null;
|
||||
}
|
||||
BranchSession branchSession = new BranchSession();
|
||||
branchSession.setXid(branchTransactionDO.getXid());
|
||||
branchSession.setTransactionId(branchTransactionDO.getTransactionId());
|
||||
branchSession.setApplicationData(branchTransactionDO.getApplicationData());
|
||||
branchSession.setBranchId(branchTransactionDO.getBranchId());
|
||||
branchSession.setBranchType(BranchType.valueOf(branchTransactionDO.getBranchType()));
|
||||
branchSession.setResourceId(branchTransactionDO.getResourceId());
|
||||
branchSession.setClientId(branchTransactionDO.getClientId());
|
||||
branchSession.setResourceGroupId(branchTransactionDO.getResourceGroupId());
|
||||
branchSession.setStatus(BranchStatus.get(branchTransactionDO.getStatus()));
|
||||
return branchSession;
|
||||
}
|
||||
public static BranchSession convertBranchSession(BranchTransactionDO branchTransactionDO) {
|
||||
if (branchTransactionDO == null) {
|
||||
return null;
|
||||
}
|
||||
BranchSession branchSession = new BranchSession();
|
||||
branchSession.setXid(branchTransactionDO.getXid());
|
||||
branchSession.setTransactionId(branchTransactionDO.getTransactionId());
|
||||
branchSession.setApplicationData(branchTransactionDO.getApplicationData());
|
||||
branchSession.setBranchId(branchTransactionDO.getBranchId());
|
||||
branchSession.setBranchType(BranchType.valueOf(branchTransactionDO.getBranchType()));
|
||||
branchSession.setResourceId(branchTransactionDO.getResourceId());
|
||||
branchSession.setClientId(branchTransactionDO.getClientId());
|
||||
branchSession.setResourceGroupId(branchTransactionDO.getResourceGroupId());
|
||||
branchSession.setStatus(BranchStatus.get(branchTransactionDO.getStatus()));
|
||||
return branchSession;
|
||||
}
|
||||
|
||||
public static GlobalTransactionDO convertGlobalTransactionDO(SessionStorable session) {
|
||||
if (session == null || !(session instanceof GlobalSession)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The parameter of SessionStorable is not available, SessionStorable:" + StringUtils.toString(session));
|
||||
}
|
||||
GlobalSession globalSession = (GlobalSession)session;
|
||||
public static GlobalTransactionDO convertGlobalTransactionDO(SessionStorable session) {
|
||||
if (session == null || !(session instanceof GlobalSession)) {
|
||||
throw new IllegalArgumentException("The parameter of SessionStorable is not available, SessionStorable:"
|
||||
+ StringUtils.toString(session));
|
||||
}
|
||||
GlobalSession globalSession = (GlobalSession) session;
|
||||
|
||||
GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
|
||||
globalTransactionDO.setXid(globalSession.getXid());
|
||||
globalTransactionDO.setStatus(globalSession.getStatus().getCode());
|
||||
globalTransactionDO.setApplicationId(globalSession.getApplicationId());
|
||||
globalTransactionDO.setBeginTime(globalSession.getBeginTime());
|
||||
globalTransactionDO.setTimeout(globalSession.getTimeout());
|
||||
globalTransactionDO.setTransactionId(globalSession.getTransactionId());
|
||||
globalTransactionDO.setTransactionName(globalSession.getTransactionName());
|
||||
globalTransactionDO.setTransactionServiceGroup(globalSession.getTransactionServiceGroup());
|
||||
globalTransactionDO.setApplicationData(globalSession.getApplicationData());
|
||||
return globalTransactionDO;
|
||||
}
|
||||
GlobalTransactionDO globalTransactionDO = new GlobalTransactionDO();
|
||||
globalTransactionDO.setXid(globalSession.getXid());
|
||||
globalTransactionDO.setStatus(globalSession.getStatus().getCode());
|
||||
globalTransactionDO.setApplicationId(globalSession.getApplicationId());
|
||||
globalTransactionDO.setBeginTime(globalSession.getBeginTime());
|
||||
globalTransactionDO.setTimeout(globalSession.getTimeout());
|
||||
globalTransactionDO.setTransactionId(globalSession.getTransactionId());
|
||||
globalTransactionDO.setTransactionName(globalSession.getTransactionName());
|
||||
globalTransactionDO.setTransactionServiceGroup(globalSession.getTransactionServiceGroup());
|
||||
globalTransactionDO.setApplicationData(globalSession.getApplicationData());
|
||||
return globalTransactionDO;
|
||||
}
|
||||
|
||||
public static BranchTransactionDO convertBranchTransactionDO(SessionStorable session) {
|
||||
if (session == null || !(session instanceof BranchSession)) {
|
||||
throw new IllegalArgumentException(
|
||||
"The parameter of SessionStorable is not available, SessionStorable:" + StringUtils.toString(session));
|
||||
}
|
||||
BranchSession branchSession = (BranchSession)session;
|
||||
BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
|
||||
branchTransactionDO.setXid(branchSession.getXid());
|
||||
branchTransactionDO.setBranchId(branchSession.getBranchId());
|
||||
branchTransactionDO.setBranchType(branchSession.getBranchType().name());
|
||||
branchTransactionDO.setClientId(branchSession.getClientId());
|
||||
branchTransactionDO.setResourceGroupId(branchSession.getResourceGroupId());
|
||||
branchTransactionDO.setTransactionId(branchSession.getTransactionId());
|
||||
branchTransactionDO.setApplicationData(branchSession.getApplicationData());
|
||||
branchTransactionDO.setResourceId(branchSession.getResourceId());
|
||||
branchTransactionDO.setStatus(branchSession.getStatus().getCode());
|
||||
return branchTransactionDO;
|
||||
}
|
||||
public static BranchTransactionDO convertBranchTransactionDO(SessionStorable session) {
|
||||
if (session == null || !(session instanceof BranchSession)) {
|
||||
throw new IllegalArgumentException("The parameter of SessionStorable is not available, SessionStorable:"
|
||||
+ StringUtils.toString(session));
|
||||
}
|
||||
BranchSession branchSession = (BranchSession) session;
|
||||
BranchTransactionDO branchTransactionDO = new BranchTransactionDO();
|
||||
branchTransactionDO.setXid(branchSession.getXid());
|
||||
branchTransactionDO.setBranchId(branchSession.getBranchId());
|
||||
branchTransactionDO.setBranchType(branchSession.getBranchType().name());
|
||||
branchTransactionDO.setClientId(branchSession.getClientId());
|
||||
branchTransactionDO.setResourceGroupId(branchSession.getResourceGroupId());
|
||||
branchTransactionDO.setTransactionId(branchSession.getTransactionId());
|
||||
branchTransactionDO.setApplicationData(branchSession.getApplicationData());
|
||||
branchTransactionDO.setResourceId(branchSession.getResourceId());
|
||||
branchTransactionDO.setStatus(branchSession.getStatus().getCode());
|
||||
return branchTransactionDO;
|
||||
}
|
||||
|
||||
public static void convertToGlobalSessionVo(List<GlobalSessionVO> result, List<GlobalSession> globalSessions) {
|
||||
if (CollectionUtils.isNotEmpty(globalSessions)) {
|
||||
for (GlobalSession globalSession : globalSessions) {
|
||||
GlobalSessionVO globalSessionVO = new GlobalSessionVO();
|
||||
BeanUtils.copyProperties(globalSession,globalSessionVO);
|
||||
globalSessionVO.setStatus(globalSession.getStatus().getCode());
|
||||
globalSessionVO.setTimeout(Long.valueOf(globalSession.getTimeout()));
|
||||
globalSessionVO.setBranchSessionVOs(converToBranchSession(globalSession.getBranchSessions()));
|
||||
result.add(globalSessionVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void convertToGlobalSessionVo(List<GlobalSessionVO> result, List<GlobalSession> globalSessions) {
|
||||
if (CollectionUtils.isNotEmpty(globalSessions)) {
|
||||
for (GlobalSession globalSession : globalSessions) {
|
||||
GlobalSessionVO globalSessionVO = new GlobalSessionVO();
|
||||
BeanUtils.copyProperties(globalSession, globalSessionVO);
|
||||
globalSessionVO.setStatus(globalSession.getStatus().getCode());
|
||||
globalSessionVO.setTimeout(Long.valueOf(globalSession.getTimeout()));
|
||||
globalSessionVO.setBranchSessionVOs(converToBranchSession(globalSession.getBranchSessions()));
|
||||
result.add(globalSessionVO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<BranchSessionVO> converToBranchSession(List<BranchSession> branchSessions) {
|
||||
Set<BranchSessionVO> branchSessionVOs = new HashSet<>(branchSessions.size());
|
||||
if (CollectionUtils.isNotEmpty(branchSessions)) {
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
BranchSessionVO branchSessionVONew = new BranchSessionVO();
|
||||
BeanUtils.copyProperties(branchSession,branchSessionVONew);
|
||||
public static Set<BranchSessionVO> converToBranchSession(List<BranchSession> branchSessions) {
|
||||
Set<BranchSessionVO> branchSessionVOs = new HashSet<>(branchSessions.size());
|
||||
if (CollectionUtils.isNotEmpty(branchSessions)) {
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
BranchSessionVO branchSessionVONew = new BranchSessionVO();
|
||||
BeanUtils.copyProperties(branchSession, branchSessionVONew);
|
||||
|
||||
branchSessionVONew.setBranchType(branchSession.getBranchType().name());
|
||||
branchSessionVONew.setStatus(branchSession.getStatus().getCode());
|
||||
branchSessionVOs.add(branchSessionVONew);
|
||||
}
|
||||
}
|
||||
return branchSessionVOs;
|
||||
}
|
||||
branchSessionVONew.setBranchType(branchSession.getBranchType().name());
|
||||
branchSessionVONew.setStatus(branchSession.getStatus().getCode());
|
||||
branchSessionVOs.add(branchSessionVONew);
|
||||
}
|
||||
}
|
||||
return branchSessionVOs;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert GlobalSession to GlobalSessionVO
|
||||
*
|
||||
* @param filteredSessions the GlobalSession list
|
||||
* @return the GlobalSessionVO list
|
||||
*/
|
||||
public static List<GlobalSessionVO> convertGlobalSession(List<GlobalSession> filteredSessions) {
|
||||
/**
|
||||
* convert GlobalSession to GlobalSessionVO
|
||||
* @param filteredSessions the GlobalSession list
|
||||
* @return the GlobalSessionVO list
|
||||
*/
|
||||
public static List<GlobalSessionVO> convertGlobalSession(List<GlobalSession> filteredSessions) {
|
||||
|
||||
if (CollectionUtils.isEmpty(filteredSessions)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
if (CollectionUtils.isEmpty(filteredSessions)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
final ArrayList<GlobalSessionVO> result = new ArrayList<>(filteredSessions.size());
|
||||
final ArrayList<GlobalSessionVO> result = new ArrayList<>(filteredSessions.size());
|
||||
|
||||
for (GlobalSession session : filteredSessions) {
|
||||
result.add(new GlobalSessionVO(
|
||||
session.getXid(),
|
||||
session.getTransactionId(),
|
||||
session.getStatus().getCode(),
|
||||
session.getApplicationId(),
|
||||
session.getTransactionServiceGroup(),
|
||||
session.getTransactionName(),
|
||||
(long) session.getTimeout(),
|
||||
session.getBeginTime(),
|
||||
session.getApplicationData(),
|
||||
convertBranchSession(session.getBranchSessions())
|
||||
));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
for (GlobalSession session : filteredSessions) {
|
||||
result.add(new GlobalSessionVO(session.getXid(), session.getTransactionId(), session.getStatus().getCode(),
|
||||
session.getApplicationId(), session.getTransactionServiceGroup(), session.getTransactionName(),
|
||||
(long) session.getTimeout(), session.getBeginTime(), session.getApplicationData(),
|
||||
convertBranchSession(session.getBranchSessions())));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert BranchSession to BranchSessionVO
|
||||
*
|
||||
* @param branchSessions the BranchSession list
|
||||
* @return the BranchSessionVO list
|
||||
*/
|
||||
public static Set<BranchSessionVO> convertBranchSession(List<BranchSession> branchSessions) {
|
||||
/**
|
||||
* convert BranchSession to BranchSessionVO
|
||||
* @param branchSessions the BranchSession list
|
||||
* @return the BranchSessionVO list
|
||||
*/
|
||||
public static Set<BranchSessionVO> convertBranchSession(List<BranchSession> branchSessions) {
|
||||
|
||||
if (CollectionUtils.isEmpty(branchSessions)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
if (CollectionUtils.isEmpty(branchSessions)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
final Set<BranchSessionVO> result = new HashSet<>(branchSessions.size());
|
||||
final Set<BranchSessionVO> result = new HashSet<>(branchSessions.size());
|
||||
|
||||
for (BranchSession session : branchSessions) {
|
||||
result.add(new BranchSessionVO(
|
||||
session.getXid(),
|
||||
session.getTransactionId(),
|
||||
session.getBranchId(),
|
||||
session.getResourceGroupId(),
|
||||
session.getResourceId(),
|
||||
session.getBranchType().name(),
|
||||
session.getStatus().getCode(),
|
||||
session.getClientId(),
|
||||
session.getApplicationData()
|
||||
));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
for (BranchSession session : branchSessions) {
|
||||
result.add(new BranchSessionVO(session.getXid(), session.getTransactionId(), session.getBranchId(),
|
||||
session.getResourceGroupId(), session.getResourceId(), session.getBranchType().name(),
|
||||
session.getStatus().getCode(), session.getClientId(), session.getApplicationData()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
+184
-172
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package io.seata.server.storage.db.lock;
|
||||
|
||||
|
||||
import io.seata.common.exception.ShouldNeverHappenException;
|
||||
import io.seata.common.loader.EnhancedServiceLoader;
|
||||
import io.seata.common.loader.LoadLevel;
|
||||
@@ -46,206 +45,219 @@ import static io.seata.core.constants.ConfigurationKeys.DISTRIBUTED_LOCK_DB_TABL
|
||||
*/
|
||||
@LoadLevel(name = "db", scope = Scope.SINGLETON)
|
||||
public class DataBaseDistributedLocker implements DistributedLocker {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DataBaseDistributedLocker.class);
|
||||
|
||||
private final String dbType;
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DataBaseDistributedLocker.class);
|
||||
|
||||
private final String datasourceType;
|
||||
private final String dbType;
|
||||
|
||||
private volatile String distributedLockTable;
|
||||
private final String datasourceType;
|
||||
|
||||
private DataSource distributedLockDataSource;
|
||||
private volatile String distributedLockTable;
|
||||
|
||||
/**
|
||||
* whether the distribute lock demotion
|
||||
* using for 1.5.0 only and will remove in 1.6.0
|
||||
*/
|
||||
@Deprecated
|
||||
private volatile boolean demotion;
|
||||
private DataSource distributedLockDataSource;
|
||||
|
||||
/**
|
||||
* Instantiates a new Log store data base dao.
|
||||
*/
|
||||
public DataBaseDistributedLocker() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
/**
|
||||
* whether the distribute lock demotion using for 1.5.0 only and will remove in 1.6.0
|
||||
*/
|
||||
@Deprecated
|
||||
private volatile boolean demotion;
|
||||
|
||||
distributedLockTable = configuration.getConfig(DISTRIBUTED_LOCK_DB_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
datasourceType = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
/**
|
||||
* Instantiates a new Log store data base dao.
|
||||
*/
|
||||
public DataBaseDistributedLocker() {
|
||||
Configuration configuration = ConfigurationFactory.getInstance();
|
||||
|
||||
if (StringUtils.isBlank(distributedLockTable)) {
|
||||
demotion = true;
|
||||
ConfigurationCache.addConfigListener(DISTRIBUTED_LOCK_DB_TABLE, new ConfigurationChangeListener() {
|
||||
@Override
|
||||
public void onChangeEvent(ConfigurationChangeEvent event) {
|
||||
String newValue = event.getNewValue();
|
||||
if (StringUtils.isNotBlank(newValue)) {
|
||||
distributedLockTable = newValue;
|
||||
init();
|
||||
demotion = false;
|
||||
ConfigurationCache.removeConfigListener(DISTRIBUTED_LOCK_DB_TABLE, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
distributedLockTable = configuration.getConfig(DISTRIBUTED_LOCK_DB_TABLE);
|
||||
dbType = configuration.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
datasourceType = configuration.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
|
||||
LOGGER.error("The distribute lock table is not config, please create the target table and config it");
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isBlank(distributedLockTable)) {
|
||||
demotion = true;
|
||||
ConfigurationCache.addConfigListener(DISTRIBUTED_LOCK_DB_TABLE, new ConfigurationChangeListener() {
|
||||
@Override
|
||||
public void onChangeEvent(ConfigurationChangeEvent event) {
|
||||
String newValue = event.getNewValue();
|
||||
if (StringUtils.isNotBlank(newValue)) {
|
||||
distributedLockTable = newValue;
|
||||
init();
|
||||
demotion = false;
|
||||
ConfigurationCache.removeConfigListener(DISTRIBUTED_LOCK_DB_TABLE, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
init();
|
||||
}
|
||||
LOGGER.error("The distribute lock table is not config, please create the target table and config it");
|
||||
return;
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(DistributedLockDO distributedLockDO) {
|
||||
if (demotion) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(DistributedLockDO distributedLockDO) {
|
||||
if (demotion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Connection connection = null;
|
||||
boolean originalAutoCommit = false;
|
||||
try {
|
||||
connection = distributedLockDataSource.getConnection();
|
||||
originalAutoCommit = connection.getAutoCommit();
|
||||
connection.setAutoCommit(false);
|
||||
Connection connection = null;
|
||||
boolean originalAutoCommit = false;
|
||||
try {
|
||||
connection = distributedLockDataSource.getConnection();
|
||||
originalAutoCommit = connection.getAutoCommit();
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
DistributedLockDO distributedLockDOFromDB = getDistributedLockDO(connection, distributedLockDO.getLockKey());
|
||||
if (null == distributedLockDOFromDB) {
|
||||
boolean ret = insertDistribute(connection, distributedLockDO);
|
||||
connection.commit();
|
||||
return ret;
|
||||
}
|
||||
DistributedLockDO distributedLockDOFromDB = getDistributedLockDO(connection,
|
||||
distributedLockDO.getLockKey());
|
||||
if (null == distributedLockDOFromDB) {
|
||||
boolean ret = insertDistribute(connection, distributedLockDO);
|
||||
connection.commit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (distributedLockDOFromDB.getExpireTime() >= System.currentTimeMillis()) {
|
||||
LOGGER.debug("the distribute lock for key :{} is holding by :{}, acquire lock failure.",
|
||||
distributedLockDO.getLockKey(), distributedLockDOFromDB.getLockValue());
|
||||
connection.commit();
|
||||
return false;
|
||||
}
|
||||
if (distributedLockDOFromDB.getExpireTime() >= System.currentTimeMillis()) {
|
||||
LOGGER.debug("the distribute lock for key :{} is holding by :{}, acquire lock failure.",
|
||||
distributedLockDO.getLockKey(), distributedLockDOFromDB.getLockValue());
|
||||
connection.commit();
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean ret = updateDistributedLock(connection, distributedLockDO);
|
||||
connection.commit();
|
||||
boolean ret = updateDistributedLock(connection, distributedLockDO);
|
||||
connection.commit();
|
||||
|
||||
return ret;
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.error("execute acquire lock failure, key is: {}", distributedLockDO.getLockKey(), ex);
|
||||
try {
|
||||
if (connection != null) {
|
||||
connection.rollback();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LOGGER.warn("rollback fail because of {}", e.getMessage(), e);
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (originalAutoCommit) {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
IOUtil.close(connection);
|
||||
} catch (SQLException ignore) { }
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
LOGGER.error("execute acquire lock failure, key is: {}", distributedLockDO.getLockKey(), ex);
|
||||
try {
|
||||
if (connection != null) {
|
||||
connection.rollback();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
LOGGER.warn("rollback fail because of {}", e.getMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (originalAutoCommit) {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
IOUtil.close(connection);
|
||||
}
|
||||
catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(DistributedLockDO distributedLockDO) {
|
||||
if (demotion) {
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(DistributedLockDO distributedLockDO) {
|
||||
if (demotion) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Connection connection = null;
|
||||
boolean originalAutoCommit = false;
|
||||
try {
|
||||
connection = distributedLockDataSource.getConnection();
|
||||
originalAutoCommit = connection.getAutoCommit();
|
||||
connection.setAutoCommit(false);
|
||||
Connection connection = null;
|
||||
boolean originalAutoCommit = false;
|
||||
try {
|
||||
connection = distributedLockDataSource.getConnection();
|
||||
originalAutoCommit = connection.getAutoCommit();
|
||||
connection.setAutoCommit(false);
|
||||
|
||||
DistributedLockDO distributedLockDOFromDB = getDistributedLockDO(connection, distributedLockDO.getLockKey());
|
||||
if (null == distributedLockDOFromDB) {
|
||||
throw new ShouldNeverHappenException("distributedLockDO would not be null when release distribute lock");
|
||||
}
|
||||
DistributedLockDO distributedLockDOFromDB = getDistributedLockDO(connection,
|
||||
distributedLockDO.getLockKey());
|
||||
if (null == distributedLockDOFromDB) {
|
||||
throw new ShouldNeverHappenException(
|
||||
"distributedLockDO would not be null when release distribute lock");
|
||||
}
|
||||
|
||||
if (distributedLockDOFromDB.getExpireTime() >= System.currentTimeMillis()
|
||||
&& !Objects.equals(distributedLockDOFromDB.getLockValue(), distributedLockDO.getLockValue())) {
|
||||
LOGGER.debug("the distribute lock for key :{} is holding by :{}, skip the release lock.",
|
||||
distributedLockDO.getLockKey(), distributedLockDOFromDB.getLockValue());
|
||||
connection.commit();
|
||||
return true;
|
||||
}
|
||||
if (distributedLockDOFromDB.getExpireTime() >= System.currentTimeMillis()
|
||||
&& !Objects.equals(distributedLockDOFromDB.getLockValue(), distributedLockDO.getLockValue())) {
|
||||
LOGGER.debug("the distribute lock for key :{} is holding by :{}, skip the release lock.",
|
||||
distributedLockDO.getLockKey(), distributedLockDOFromDB.getLockValue());
|
||||
connection.commit();
|
||||
return true;
|
||||
}
|
||||
|
||||
distributedLockDO.setLockValue(StringUtils.SPACE);
|
||||
distributedLockDO.setExpireTime(0L);
|
||||
boolean ret = updateDistributedLock(connection, distributedLockDO);
|
||||
distributedLockDO.setLockValue(StringUtils.SPACE);
|
||||
distributedLockDO.setExpireTime(0L);
|
||||
boolean ret = updateDistributedLock(connection, distributedLockDO);
|
||||
|
||||
connection.commit();
|
||||
return ret;
|
||||
} catch (SQLException ex) {
|
||||
LOGGER.error("execute release lock failure, key is: {}", distributedLockDO.getLockKey(), ex);
|
||||
connection.commit();
|
||||
return ret;
|
||||
}
|
||||
catch (SQLException ex) {
|
||||
LOGGER.error("execute release lock failure, key is: {}", distributedLockDO.getLockKey(), ex);
|
||||
|
||||
try {
|
||||
if (connection != null) {
|
||||
connection.rollback();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LOGGER.warn("rollback fail because of {}", e.getMessage(), e);
|
||||
}
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (originalAutoCommit) {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
IOUtil.close(connection);
|
||||
} catch (SQLException ignore) { }
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (connection != null) {
|
||||
connection.rollback();
|
||||
}
|
||||
}
|
||||
catch (SQLException e) {
|
||||
LOGGER.warn("rollback fail because of {}", e.getMessage(), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
if (originalAutoCommit) {
|
||||
connection.setAutoCommit(true);
|
||||
}
|
||||
IOUtil.close(connection);
|
||||
}
|
||||
catch (SQLException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DistributedLockDO getDistributedLockDO(Connection connection, String key) throws SQLException {
|
||||
try (PreparedStatement pst = connection.prepareStatement(DistributedLockSqlFactory.getDistributedLogStoreSql(dbType)
|
||||
.getSelectDistributeForUpdateSql(distributedLockTable))) {
|
||||
protected DistributedLockDO getDistributedLockDO(Connection connection, String key) throws SQLException {
|
||||
try (PreparedStatement pst = connection.prepareStatement(DistributedLockSqlFactory
|
||||
.getDistributedLogStoreSql(dbType).getSelectDistributeForUpdateSql(distributedLockTable))) {
|
||||
|
||||
pst.setString(1, key);
|
||||
ResultSet resultSet = pst.executeQuery();
|
||||
pst.setString(1, key);
|
||||
ResultSet resultSet = pst.executeQuery();
|
||||
|
||||
if (resultSet.next()) {
|
||||
DistributedLockDO distributedLock = new DistributedLockDO();
|
||||
distributedLock.setExpireTime(resultSet.getLong(ServerTableColumnsName.DISTRIBUTED_LOCK_EXPIRE));
|
||||
distributedLock.setLockValue(resultSet.getString(ServerTableColumnsName.DISTRIBUTED_LOCK_VALUE));
|
||||
distributedLock.setLockKey(key);
|
||||
return distributedLock;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (resultSet.next()) {
|
||||
DistributedLockDO distributedLock = new DistributedLockDO();
|
||||
distributedLock.setExpireTime(resultSet.getLong(ServerTableColumnsName.DISTRIBUTED_LOCK_EXPIRE));
|
||||
distributedLock.setLockValue(resultSet.getString(ServerTableColumnsName.DISTRIBUTED_LOCK_VALUE));
|
||||
distributedLock.setLockKey(key);
|
||||
return distributedLock;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean insertDistribute(Connection connection, DistributedLockDO distributedLockDO) throws SQLException {
|
||||
try (PreparedStatement insertPst = connection.prepareStatement(DistributedLockSqlFactory.getDistributedLogStoreSql(dbType)
|
||||
.getInsertSql(distributedLockTable))) {
|
||||
insertPst.setString(1, distributedLockDO.getLockKey());
|
||||
insertPst.setString(2, distributedLockDO.getLockValue());
|
||||
if (distributedLockDO.getExpireTime() > 0) {
|
||||
distributedLockDO.setExpireTime(distributedLockDO.getExpireTime() + System.currentTimeMillis());
|
||||
}
|
||||
insertPst.setLong(3, distributedLockDO.getExpireTime());
|
||||
return insertPst.executeUpdate() > 0;
|
||||
}
|
||||
}
|
||||
protected boolean insertDistribute(Connection connection, DistributedLockDO distributedLockDO) throws SQLException {
|
||||
try (PreparedStatement insertPst = connection.prepareStatement(
|
||||
DistributedLockSqlFactory.getDistributedLogStoreSql(dbType).getInsertSql(distributedLockTable))) {
|
||||
insertPst.setString(1, distributedLockDO.getLockKey());
|
||||
insertPst.setString(2, distributedLockDO.getLockValue());
|
||||
if (distributedLockDO.getExpireTime() > 0) {
|
||||
distributedLockDO.setExpireTime(distributedLockDO.getExpireTime() + System.currentTimeMillis());
|
||||
}
|
||||
insertPst.setLong(3, distributedLockDO.getExpireTime());
|
||||
return insertPst.executeUpdate() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean updateDistributedLock(Connection connection, DistributedLockDO distributedLockDO) throws SQLException {
|
||||
try (PreparedStatement updatePst = connection.prepareStatement(DistributedLockSqlFactory.getDistributedLogStoreSql(dbType)
|
||||
.getUpdateSql(distributedLockTable))) {
|
||||
updatePst.setString(1, distributedLockDO.getLockValue());
|
||||
if (distributedLockDO.getExpireTime() > 0) {
|
||||
distributedLockDO.setExpireTime(distributedLockDO.getExpireTime() + System.currentTimeMillis());
|
||||
}
|
||||
updatePst.setLong(2, distributedLockDO.getExpireTime());
|
||||
updatePst.setString(3, distributedLockDO.getLockKey());
|
||||
return updatePst.executeUpdate() > 0;
|
||||
}
|
||||
}
|
||||
protected boolean updateDistributedLock(Connection connection, DistributedLockDO distributedLockDO)
|
||||
throws SQLException {
|
||||
try (PreparedStatement updatePst = connection.prepareStatement(
|
||||
DistributedLockSqlFactory.getDistributedLogStoreSql(dbType).getUpdateSql(distributedLockTable))) {
|
||||
updatePst.setString(1, distributedLockDO.getLockValue());
|
||||
if (distributedLockDO.getExpireTime() > 0) {
|
||||
distributedLockDO.setExpireTime(distributedLockDO.getExpireTime() + System.currentTimeMillis());
|
||||
}
|
||||
updatePst.setLong(2, distributedLockDO.getExpireTime());
|
||||
updatePst.setString(3, distributedLockDO.getLockKey());
|
||||
return updatePst.executeUpdate() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
this.distributedLockDataSource = EnhancedServiceLoader.load(DataSourceProvider.class, datasourceType).provide();
|
||||
}
|
||||
private void init() {
|
||||
this.distributedLockDataSource = EnhancedServiceLoader.load(DataSourceProvider.class, datasourceType).provide();
|
||||
}
|
||||
|
||||
}
|
||||
+36
-33
@@ -37,42 +37,45 @@ import javax.sql.DataSource;
|
||||
@LoadLevel(name = "db")
|
||||
public class DataBaseLockManager extends AbstractLockManager implements Initialize {
|
||||
|
||||
/**
|
||||
* The locker.
|
||||
*/
|
||||
private Locker locker;
|
||||
/**
|
||||
* The locker.
|
||||
*/
|
||||
private Locker locker;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
// init dataSource
|
||||
String datasourceType = ConfigurationFactory.getInstance().getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
DataSource lockStoreDataSource = EnhancedServiceLoader.load(DataSourceProvider.class, datasourceType).provide();
|
||||
locker = new DataBaseLocker(lockStoreDataSource);
|
||||
}
|
||||
@Override
|
||||
public void init() {
|
||||
// init dataSource
|
||||
String datasourceType = ConfigurationFactory.getInstance()
|
||||
.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
DataSource lockStoreDataSource = EnhancedServiceLoader.load(DataSourceProvider.class, datasourceType).provide();
|
||||
locker = new DataBaseLocker(lockStoreDataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(BranchSession branchSession) throws TransactionException {
|
||||
try {
|
||||
return getLocker().releaseLock(branchSession.getXid(), branchSession.getBranchId());
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("unLock error, xid {}, branchId:{}", branchSession.getXid(), branchSession.getBranchId(), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(BranchSession branchSession) throws TransactionException {
|
||||
try {
|
||||
return getLocker().releaseLock(branchSession.getXid(), branchSession.getBranchId());
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("unLock error, xid {}, branchId:{}", branchSession.getXid(), branchSession.getBranchId(), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locker getLocker(BranchSession branchSession) {
|
||||
return locker;
|
||||
}
|
||||
@Override
|
||||
public Locker getLocker(BranchSession branchSession) {
|
||||
return locker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException {
|
||||
try {
|
||||
return getLocker().releaseLock(globalSession.getXid());
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("unLock globalSession error, xid:{}", globalSession.getXid(), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException {
|
||||
try {
|
||||
return getLocker().releaseLock(globalSession.getXid());
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("unLock globalSession error, xid:{}", globalSession.getXid(), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+105
-97
@@ -33,112 +33,120 @@ import java.util.List;
|
||||
*/
|
||||
public class DataBaseLocker extends AbstractLocker {
|
||||
|
||||
private LockStore lockStore;
|
||||
private LockStore lockStore;
|
||||
|
||||
/**
|
||||
* Instantiates a new Data base locker.
|
||||
*/
|
||||
public DataBaseLocker() {
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Data base locker.
|
||||
*/
|
||||
public DataBaseLocker() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Data base locker.
|
||||
*
|
||||
* @param logStoreDataSource the log store data source
|
||||
*/
|
||||
public DataBaseLocker(DataSource logStoreDataSource) {
|
||||
lockStore = new LockStoreDataBaseDAO(logStoreDataSource);
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Data base locker.
|
||||
* @param logStoreDataSource the log store data source
|
||||
*/
|
||||
public DataBaseLocker(DataSource logStoreDataSource) {
|
||||
lockStore = new LockStoreDataBaseDAO(logStoreDataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> locks) {
|
||||
return acquireLock(locks, true, false);
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> locks) {
|
||||
return acquireLock(locks, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> locks, boolean autoCommit, boolean skipCheckLock) {
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return lockStore.acquireLock(convertToLockDO(locks), autoCommit, skipCheckLock);
|
||||
} catch (StoreException e) {
|
||||
throw e;
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("AcquireLock error, locks:{}", CollectionUtils.toString(locks), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> locks, boolean autoCommit, boolean skipCheckLock) {
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return lockStore.acquireLock(convertToLockDO(locks), autoCommit, skipCheckLock);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("AcquireLock error, locks:{}", CollectionUtils.toString(locks), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(List<RowLock> locks) {
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return lockStore.unLock(convertToLockDO(locks));
|
||||
} catch (StoreException e) {
|
||||
throw e;
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("unLock error, locks:{}", CollectionUtils.toString(locks), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(List<RowLock> locks) {
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return lockStore.unLock(convertToLockDO(locks));
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("unLock error, locks:{}", CollectionUtils.toString(locks), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(String xid, Long branchId) {
|
||||
try {
|
||||
return lockStore.unLock(branchId);
|
||||
} catch (StoreException e) {
|
||||
throw e;
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("unLock by branchId error, xid {}, branchId:{}", xid, branchId, t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(String xid, Long branchId) {
|
||||
try {
|
||||
return lockStore.unLock(branchId);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("unLock by branchId error, xid {}, branchId:{}", xid, branchId, t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(String xid) {
|
||||
try {
|
||||
return lockStore.unLock(xid);
|
||||
} catch (StoreException e) {
|
||||
throw e;
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("unLock by branchIds error, xid {}", xid, t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(String xid) {
|
||||
try {
|
||||
return lockStore.unLock(xid);
|
||||
}
|
||||
catch (StoreException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("unLock by branchIds error, xid {}", xid, t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLockable(List<RowLock> locks) {
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return lockStore.isLockable(convertToLockDO(locks));
|
||||
} catch (DataAccessException e) {
|
||||
throw e;
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("isLockable error, locks:{}", CollectionUtils.toString(locks), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean isLockable(List<RowLock> locks) {
|
||||
if (CollectionUtils.isEmpty(locks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
return lockStore.isLockable(convertToLockDO(locks));
|
||||
}
|
||||
catch (DataAccessException e) {
|
||||
throw e;
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("isLockable error, locks:{}", CollectionUtils.toString(locks), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
lockStore.updateLockStatus(xid, lockStatus);
|
||||
}
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
lockStore.updateLockStatus(xid, lockStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets lock store.
|
||||
*
|
||||
* @param lockStore the lock store
|
||||
*/
|
||||
public void setLockStore(LockStore lockStore) {
|
||||
this.lockStore = lockStore;
|
||||
}
|
||||
/**
|
||||
* Sets lock store.
|
||||
* @param lockStore the lock store
|
||||
*/
|
||||
public void setLockStore(LockStore lockStore) {
|
||||
this.lockStore = lockStore;
|
||||
}
|
||||
|
||||
}
|
||||
+381
-358
@@ -51,387 +51,410 @@ import static io.seata.core.exception.TransactionExceptionCode.LockKeyConflictFa
|
||||
*/
|
||||
public class LockStoreDataBaseDAO implements LockStore {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LockStoreDataBaseDAO.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(LockStoreDataBaseDAO.class);
|
||||
|
||||
/**
|
||||
* The constant CONFIG.
|
||||
*/
|
||||
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
/**
|
||||
* The constant CONFIG.
|
||||
*/
|
||||
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
|
||||
/**
|
||||
* The Lock store data source.
|
||||
*/
|
||||
protected DataSource lockStoreDataSource;
|
||||
/**
|
||||
* The Lock store data source.
|
||||
*/
|
||||
protected DataSource lockStoreDataSource;
|
||||
|
||||
/**
|
||||
* The Lock table.
|
||||
*/
|
||||
protected String lockTable;
|
||||
/**
|
||||
* The Lock table.
|
||||
*/
|
||||
protected String lockTable;
|
||||
|
||||
/**
|
||||
* The Db type.
|
||||
*/
|
||||
protected String dbType;
|
||||
/**
|
||||
* The Db type.
|
||||
*/
|
||||
protected String dbType;
|
||||
|
||||
/**
|
||||
* Instantiates a new Data base lock store dao.
|
||||
*
|
||||
* @param lockStoreDataSource the log store data source
|
||||
*/
|
||||
public LockStoreDataBaseDAO(DataSource lockStoreDataSource) {
|
||||
this.lockStoreDataSource = lockStoreDataSource;
|
||||
lockTable = CONFIG.getConfig(ConfigurationKeys.LOCK_DB_TABLE, DEFAULT_LOCK_DB_TABLE);
|
||||
dbType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new StoreException("there must be db type.");
|
||||
}
|
||||
if (lockStoreDataSource == null) {
|
||||
throw new StoreException("there must be lockStoreDataSource.");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Data base lock store dao.
|
||||
* @param lockStoreDataSource the log store data source
|
||||
*/
|
||||
public LockStoreDataBaseDAO(DataSource lockStoreDataSource) {
|
||||
this.lockStoreDataSource = lockStoreDataSource;
|
||||
lockTable = CONFIG.getConfig(ConfigurationKeys.LOCK_DB_TABLE, DEFAULT_LOCK_DB_TABLE);
|
||||
dbType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_TYPE);
|
||||
if (StringUtils.isBlank(dbType)) {
|
||||
throw new StoreException("there must be db type.");
|
||||
}
|
||||
if (lockStoreDataSource == null) {
|
||||
throw new StoreException("there must be lockStoreDataSource.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(LockDO lockDO) {
|
||||
return acquireLock(Collections.singletonList(lockDO));
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(LockDO lockDO) {
|
||||
return acquireLock(Collections.singletonList(lockDO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(List<LockDO> lockDOs) {
|
||||
return acquireLock(lockDOs, true, false);
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(List<LockDO> lockDOs) {
|
||||
return acquireLock(lockDOs, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(List<LockDO> lockDOs, boolean autoCommit, boolean skipCheckLock) {
|
||||
Connection conn = null;
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
Set<String> dbExistedRowKeys = new HashSet<>();
|
||||
boolean originalAutoCommit = true;
|
||||
if (lockDOs.size() > 1) {
|
||||
lockDOs = lockDOs.stream().filter(LambdaUtils.distinctByKey(LockDO::getRowKey)).collect(Collectors.toList());
|
||||
}
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
if (originalAutoCommit = conn.getAutoCommit()) {
|
||||
conn.setAutoCommit(false);
|
||||
}
|
||||
List<LockDO> unrepeatedLockDOs = lockDOs;
|
||||
@Override
|
||||
public boolean acquireLock(List<LockDO> lockDOs, boolean autoCommit, boolean skipCheckLock) {
|
||||
Connection conn = null;
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
Set<String> dbExistedRowKeys = new HashSet<>();
|
||||
boolean originalAutoCommit = true;
|
||||
if (lockDOs.size() > 1) {
|
||||
lockDOs = lockDOs.stream().filter(LambdaUtils.distinctByKey(LockDO::getRowKey))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
if (originalAutoCommit = conn.getAutoCommit()) {
|
||||
conn.setAutoCommit(false);
|
||||
}
|
||||
List<LockDO> unrepeatedLockDOs = lockDOs;
|
||||
|
||||
//check lock
|
||||
if (!skipCheckLock) {
|
||||
// check lock
|
||||
if (!skipCheckLock) {
|
||||
|
||||
boolean canLock = true;
|
||||
//query
|
||||
String checkLockSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getCheckLockableSql(lockTable, lockDOs.size());
|
||||
ps = conn.prepareStatement(checkLockSQL);
|
||||
for (int i = 0; i < lockDOs.size(); i++) {
|
||||
ps.setString(i + 1, lockDOs.get(i).getRowKey());
|
||||
}
|
||||
rs = ps.executeQuery();
|
||||
String currentXID = lockDOs.get(0).getXid();
|
||||
boolean failFast = false;
|
||||
while (rs.next()) {
|
||||
String dbXID = rs.getString(ServerTableColumnsName.LOCK_TABLE_XID);
|
||||
if (!StringUtils.equals(dbXID, currentXID)) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
String dbPk = rs.getString(ServerTableColumnsName.LOCK_TABLE_PK);
|
||||
String dbTableName = rs.getString(ServerTableColumnsName.LOCK_TABLE_TABLE_NAME);
|
||||
long dbBranchId = rs.getLong(ServerTableColumnsName.LOCK_TABLE_BRANCH_ID);
|
||||
LOGGER.info("Global lock on [{}:{}] is holding by xid {} branchId {}", dbTableName, dbPk, dbXID, dbBranchId);
|
||||
}
|
||||
if (!autoCommit) {
|
||||
int status = rs.getInt(ServerTableColumnsName.LOCK_TABLE_STATUS);
|
||||
if (status == LockStatus.Rollbacking.getCode()) {
|
||||
failFast = true;
|
||||
}
|
||||
}
|
||||
canLock = false;
|
||||
break;
|
||||
}
|
||||
boolean canLock = true;
|
||||
// query
|
||||
String checkLockSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getCheckLockableSql(lockTable,
|
||||
lockDOs.size());
|
||||
ps = conn.prepareStatement(checkLockSQL);
|
||||
for (int i = 0; i < lockDOs.size(); i++) {
|
||||
ps.setString(i + 1, lockDOs.get(i).getRowKey());
|
||||
}
|
||||
rs = ps.executeQuery();
|
||||
String currentXID = lockDOs.get(0).getXid();
|
||||
boolean failFast = false;
|
||||
while (rs.next()) {
|
||||
String dbXID = rs.getString(ServerTableColumnsName.LOCK_TABLE_XID);
|
||||
if (!StringUtils.equals(dbXID, currentXID)) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
String dbPk = rs.getString(ServerTableColumnsName.LOCK_TABLE_PK);
|
||||
String dbTableName = rs.getString(ServerTableColumnsName.LOCK_TABLE_TABLE_NAME);
|
||||
long dbBranchId = rs.getLong(ServerTableColumnsName.LOCK_TABLE_BRANCH_ID);
|
||||
LOGGER.info("Global lock on [{}:{}] is holding by xid {} branchId {}", dbTableName, dbPk,
|
||||
dbXID, dbBranchId);
|
||||
}
|
||||
if (!autoCommit) {
|
||||
int status = rs.getInt(ServerTableColumnsName.LOCK_TABLE_STATUS);
|
||||
if (status == LockStatus.Rollbacking.getCode()) {
|
||||
failFast = true;
|
||||
}
|
||||
}
|
||||
canLock = false;
|
||||
break;
|
||||
}
|
||||
|
||||
dbExistedRowKeys.add(rs.getString(ServerTableColumnsName.LOCK_TABLE_ROW_KEY));
|
||||
}
|
||||
if (!canLock) {
|
||||
conn.rollback();
|
||||
if (failFast) {
|
||||
throw new StoreException(new BranchTransactionException(LockKeyConflictFailFast));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// If the lock has been exists in db, remove it from the lockDOs
|
||||
if (CollectionUtils.isNotEmpty(dbExistedRowKeys)) {
|
||||
unrepeatedLockDOs = lockDOs.stream().filter(lockDO -> !dbExistedRowKeys.contains(lockDO.getRowKey()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(unrepeatedLockDOs)) {
|
||||
conn.rollback();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
dbExistedRowKeys.add(rs.getString(ServerTableColumnsName.LOCK_TABLE_ROW_KEY));
|
||||
}
|
||||
if (!canLock) {
|
||||
conn.rollback();
|
||||
if (failFast) {
|
||||
throw new StoreException(new BranchTransactionException(LockKeyConflictFailFast));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// If the lock has been exists in db, remove it from the lockDOs
|
||||
if (CollectionUtils.isNotEmpty(dbExistedRowKeys)) {
|
||||
unrepeatedLockDOs = lockDOs.stream()
|
||||
.filter(lockDO -> !dbExistedRowKeys.contains(lockDO.getRowKey()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(unrepeatedLockDOs)) {
|
||||
conn.rollback();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// lock
|
||||
if (unrepeatedLockDOs.size() == 1) {
|
||||
LockDO lockDO = unrepeatedLockDOs.get(0);
|
||||
if (!doAcquireLock(conn, lockDO)) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Global lock acquire failed, xid {} branchId {} pk {}", lockDO.getXid(), lockDO.getBranchId(), lockDO.getPk());
|
||||
}
|
||||
conn.rollback();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!doAcquireLocks(conn, unrepeatedLockDOs)) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Global lock batch acquire failed, xid {} branchId {} pks {}", unrepeatedLockDOs.get(0).getXid(),
|
||||
unrepeatedLockDOs.get(0).getBranchId(), unrepeatedLockDOs.stream().map(lockDO -> lockDO.getPk()).collect(Collectors.toList()));
|
||||
}
|
||||
conn.rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
conn.commit();
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
} finally {
|
||||
IOUtil.close(rs, ps);
|
||||
if (conn != null) {
|
||||
try {
|
||||
if (originalAutoCommit) {
|
||||
conn.setAutoCommit(true);
|
||||
}
|
||||
conn.close();
|
||||
} catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// lock
|
||||
if (unrepeatedLockDOs.size() == 1) {
|
||||
LockDO lockDO = unrepeatedLockDOs.get(0);
|
||||
if (!doAcquireLock(conn, lockDO)) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Global lock acquire failed, xid {} branchId {} pk {}", lockDO.getXid(),
|
||||
lockDO.getBranchId(), lockDO.getPk());
|
||||
}
|
||||
conn.rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!doAcquireLocks(conn, unrepeatedLockDOs)) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("Global lock batch acquire failed, xid {} branchId {} pks {}",
|
||||
unrepeatedLockDOs.get(0).getXid(), unrepeatedLockDOs.get(0).getBranchId(),
|
||||
unrepeatedLockDOs.stream().map(lockDO -> lockDO.getPk()).collect(Collectors.toList()));
|
||||
}
|
||||
conn.rollback();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
conn.commit();
|
||||
return true;
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(rs, ps);
|
||||
if (conn != null) {
|
||||
try {
|
||||
if (originalAutoCommit) {
|
||||
conn.setAutoCommit(true);
|
||||
}
|
||||
conn.close();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unLock(LockDO lockDO) {
|
||||
return unLock(Collections.singletonList(lockDO));
|
||||
}
|
||||
@Override
|
||||
public boolean unLock(LockDO lockDO) {
|
||||
return unLock(Collections.singletonList(lockDO));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unLock(List<LockDO> lockDOs) {
|
||||
Connection conn = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
conn.setAutoCommit(true);
|
||||
@Override
|
||||
public boolean unLock(List<LockDO> lockDOs) {
|
||||
Connection conn = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
conn.setAutoCommit(true);
|
||||
|
||||
//batch release lock
|
||||
String batchDeleteSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getBatchDeleteLockSql(lockTable, lockDOs.size());
|
||||
ps = conn.prepareStatement(batchDeleteSQL);
|
||||
ps.setString(1, lockDOs.get(0).getXid());
|
||||
for (int i = 0; i < lockDOs.size(); i++) {
|
||||
ps.setString(i + 2, lockDOs.get(i).getRowKey());
|
||||
}
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
} finally {
|
||||
IOUtil.close(ps, conn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// batch release lock
|
||||
String batchDeleteSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getBatchDeleteLockSql(lockTable,
|
||||
lockDOs.size());
|
||||
ps = conn.prepareStatement(batchDeleteSQL);
|
||||
ps.setString(1, lockDOs.get(0).getXid());
|
||||
for (int i = 0; i < lockDOs.size(); i++) {
|
||||
ps.setString(i + 2, lockDOs.get(i).getRowKey());
|
||||
}
|
||||
ps.executeUpdate();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(ps, conn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unLock(String xid) {
|
||||
Connection conn = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
conn.setAutoCommit(true);
|
||||
//batch release lock by branch list
|
||||
String batchDeleteSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getBatchDeleteLockSqlByXid(lockTable);
|
||||
ps = conn.prepareStatement(batchDeleteSQL);
|
||||
ps.setString(1, xid);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
} finally {
|
||||
IOUtil.close(ps, conn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean unLock(String xid) {
|
||||
Connection conn = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
conn.setAutoCommit(true);
|
||||
// batch release lock by branch list
|
||||
String batchDeleteSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getBatchDeleteLockSqlByXid(lockTable);
|
||||
ps = conn.prepareStatement(batchDeleteSQL);
|
||||
ps.setString(1, xid);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(ps, conn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unLock(Long branchId) {
|
||||
Connection conn = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
conn.setAutoCommit(true);
|
||||
//batch release lock by branchId
|
||||
String batchDeleteSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getBatchDeleteLockSqlByBranchId(lockTable);
|
||||
ps = conn.prepareStatement(batchDeleteSQL);
|
||||
ps.setLong(1, branchId);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
} finally {
|
||||
IOUtil.close(ps, conn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean unLock(Long branchId) {
|
||||
Connection conn = null;
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
conn.setAutoCommit(true);
|
||||
// batch release lock by branchId
|
||||
String batchDeleteSQL = LockStoreSqlFactory.getLogStoreSql(dbType)
|
||||
.getBatchDeleteLockSqlByBranchId(lockTable);
|
||||
ps = conn.prepareStatement(batchDeleteSQL);
|
||||
ps.setLong(1, branchId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(ps, conn);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLockable(List<LockDO> lockDOs) {
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
conn.setAutoCommit(true);
|
||||
if (!checkLockable(conn, lockDOs)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
throw new DataAccessException(e);
|
||||
} finally {
|
||||
IOUtil.close(conn);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean isLockable(List<LockDO> lockDOs) {
|
||||
Connection conn = null;
|
||||
try {
|
||||
conn = lockStoreDataSource.getConnection();
|
||||
conn.setAutoCommit(true);
|
||||
if (!checkLockable(conn, lockDOs)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new DataAccessException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(conn);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
String updateStatusLockByGlobalSql =
|
||||
LockStoreSqlFactory.getLogStoreSql(dbType).getBatchUpdateStatusLockByGlobalSql(lockTable);
|
||||
try (Connection conn = lockStoreDataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(updateStatusLockByGlobalSql)) {
|
||||
conn.setAutoCommit(true);
|
||||
ps.setInt(1, lockStatus.getCode());
|
||||
ps.setString(2, xid);
|
||||
ps.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
throw new DataAccessException(e);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
String updateStatusLockByGlobalSql = LockStoreSqlFactory.getLogStoreSql(dbType)
|
||||
.getBatchUpdateStatusLockByGlobalSql(lockTable);
|
||||
try (Connection conn = lockStoreDataSource.getConnection();
|
||||
PreparedStatement ps = conn.prepareStatement(updateStatusLockByGlobalSql)) {
|
||||
conn.setAutoCommit(true);
|
||||
ps.setInt(1, lockStatus.getCode());
|
||||
ps.setString(2, xid);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new DataAccessException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do acquire lock boolean.
|
||||
*
|
||||
* @param conn the conn
|
||||
* @param lockDO the lock do
|
||||
* @return the boolean
|
||||
*/
|
||||
protected boolean doAcquireLock(Connection conn, LockDO lockDO) {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
//insert
|
||||
String insertLockSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getInsertLockSQL(lockTable);
|
||||
ps = conn.prepareStatement(insertLockSQL);
|
||||
ps.setString(1, lockDO.getXid());
|
||||
ps.setLong(2, lockDO.getTransactionId());
|
||||
ps.setLong(3, lockDO.getBranchId());
|
||||
ps.setString(4, lockDO.getResourceId());
|
||||
ps.setString(5, lockDO.getTableName());
|
||||
ps.setString(6, lockDO.getPk());
|
||||
ps.setString(7, lockDO.getRowKey());
|
||||
ps.setInt(8, LockStatus.Locked.getCode());
|
||||
return ps.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
if (e instanceof SQLIntegrityConstraintViolationException) {
|
||||
return false;
|
||||
}
|
||||
throw new StoreException(e);
|
||||
} finally {
|
||||
IOUtil.close(ps);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Do acquire lock boolean.
|
||||
* @param conn the conn
|
||||
* @param lockDO the lock do
|
||||
* @return the boolean
|
||||
*/
|
||||
protected boolean doAcquireLock(Connection conn, LockDO lockDO) {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
// insert
|
||||
String insertLockSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getInsertLockSQL(lockTable);
|
||||
ps = conn.prepareStatement(insertLockSQL);
|
||||
ps.setString(1, lockDO.getXid());
|
||||
ps.setLong(2, lockDO.getTransactionId());
|
||||
ps.setLong(3, lockDO.getBranchId());
|
||||
ps.setString(4, lockDO.getResourceId());
|
||||
ps.setString(5, lockDO.getTableName());
|
||||
ps.setString(6, lockDO.getPk());
|
||||
ps.setString(7, lockDO.getRowKey());
|
||||
ps.setInt(8, LockStatus.Locked.getCode());
|
||||
return ps.executeUpdate() > 0;
|
||||
}
|
||||
catch (SQLException e) {
|
||||
if (e instanceof SQLIntegrityConstraintViolationException) {
|
||||
return false;
|
||||
}
|
||||
throw new StoreException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(ps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do acquire lock boolean.
|
||||
*
|
||||
* @param conn the conn
|
||||
* @param lockDOs the lock do list
|
||||
* @return the boolean
|
||||
*/
|
||||
protected boolean doAcquireLocks(Connection conn, List<LockDO> lockDOs) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
//insert
|
||||
String insertLockSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getInsertLockSQL(lockTable);
|
||||
ps = conn.prepareStatement(insertLockSQL);
|
||||
for (LockDO lockDO : lockDOs) {
|
||||
ps.setString(1, lockDO.getXid());
|
||||
ps.setLong(2, lockDO.getTransactionId());
|
||||
ps.setLong(3, lockDO.getBranchId());
|
||||
ps.setString(4, lockDO.getResourceId());
|
||||
ps.setString(5, lockDO.getTableName());
|
||||
ps.setString(6, lockDO.getPk());
|
||||
ps.setString(7, lockDO.getRowKey());
|
||||
ps.setInt(8, lockDO.getStatus());
|
||||
ps.addBatch();
|
||||
}
|
||||
return ps.executeBatch().length == lockDOs.size();
|
||||
} catch (SQLIntegrityConstraintViolationException e) {
|
||||
LOGGER.error("Global lock batch acquire error: {}", e.getMessage(), e);
|
||||
//return false,let the caller go to conn.rollabck()
|
||||
return false;
|
||||
} catch (SQLException e) {
|
||||
throw e;
|
||||
} finally {
|
||||
IOUtil.close(ps);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Do acquire lock boolean.
|
||||
* @param conn the conn
|
||||
* @param lockDOs the lock do list
|
||||
* @return the boolean
|
||||
*/
|
||||
protected boolean doAcquireLocks(Connection conn, List<LockDO> lockDOs) throws SQLException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
// insert
|
||||
String insertLockSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getInsertLockSQL(lockTable);
|
||||
ps = conn.prepareStatement(insertLockSQL);
|
||||
for (LockDO lockDO : lockDOs) {
|
||||
ps.setString(1, lockDO.getXid());
|
||||
ps.setLong(2, lockDO.getTransactionId());
|
||||
ps.setLong(3, lockDO.getBranchId());
|
||||
ps.setString(4, lockDO.getResourceId());
|
||||
ps.setString(5, lockDO.getTableName());
|
||||
ps.setString(6, lockDO.getPk());
|
||||
ps.setString(7, lockDO.getRowKey());
|
||||
ps.setInt(8, lockDO.getStatus());
|
||||
ps.addBatch();
|
||||
}
|
||||
return ps.executeBatch().length == lockDOs.size();
|
||||
}
|
||||
catch (SQLIntegrityConstraintViolationException e) {
|
||||
LOGGER.error("Global lock batch acquire error: {}", e.getMessage(), e);
|
||||
// return false,let the caller go to conn.rollabck()
|
||||
return false;
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw e;
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(ps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check lock boolean.
|
||||
*
|
||||
* @param conn the conn
|
||||
* @param lockDOs the lock do
|
||||
* @return the boolean
|
||||
*/
|
||||
protected boolean checkLockable(Connection conn, List<LockDO> lockDOs) {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
//query
|
||||
String checkLockSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getCheckLockableSql(lockTable, lockDOs.size());
|
||||
ps = conn.prepareStatement(checkLockSQL);
|
||||
for (int i = 0; i < lockDOs.size(); i++) {
|
||||
ps.setString(i + 1, lockDOs.get(i).getRowKey());
|
||||
}
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
String xid = rs.getString("xid");
|
||||
if (!StringUtils.equals(xid, lockDOs.get(0).getXid())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (SQLException e) {
|
||||
throw new DataAccessException(e);
|
||||
} finally {
|
||||
IOUtil.close(rs, ps);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Check lock boolean.
|
||||
* @param conn the conn
|
||||
* @param lockDOs the lock do
|
||||
* @return the boolean
|
||||
*/
|
||||
protected boolean checkLockable(Connection conn, List<LockDO> lockDOs) {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
// query
|
||||
String checkLockSQL = LockStoreSqlFactory.getLogStoreSql(dbType).getCheckLockableSql(lockTable,
|
||||
lockDOs.size());
|
||||
ps = conn.prepareStatement(checkLockSQL);
|
||||
for (int i = 0; i < lockDOs.size(); i++) {
|
||||
ps.setString(i + 1, lockDOs.get(i).getRowKey());
|
||||
}
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
String xid = rs.getString("xid");
|
||||
if (!StringUtils.equals(xid, lockDOs.get(0).getXid())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (SQLException e) {
|
||||
throw new DataAccessException(e);
|
||||
}
|
||||
finally {
|
||||
IOUtil.close(rs, ps);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets lock table.
|
||||
*
|
||||
* @param lockTable the lock table
|
||||
*/
|
||||
public void setLockTable(String lockTable) {
|
||||
this.lockTable = lockTable;
|
||||
}
|
||||
/**
|
||||
* Sets lock table.
|
||||
* @param lockTable the lock table
|
||||
*/
|
||||
public void setLockTable(String lockTable) {
|
||||
this.lockTable = lockTable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets db type.
|
||||
*
|
||||
* @param dbType the db type
|
||||
*/
|
||||
public void setDbType(String dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
/**
|
||||
* Sets db type.
|
||||
* @param dbType the db type
|
||||
*/
|
||||
public void setDbType(String dbType) {
|
||||
this.dbType = dbType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets log store data source.
|
||||
* @param lockStoreDataSource the log store data source
|
||||
*/
|
||||
public void setLogStoreDataSource(DataSource lockStoreDataSource) {
|
||||
this.lockStoreDataSource = lockStoreDataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets log store data source.
|
||||
*
|
||||
* @param lockStoreDataSource the log store data source
|
||||
*/
|
||||
public void setLogStoreDataSource(DataSource lockStoreDataSource) {
|
||||
this.lockStoreDataSource = lockStoreDataSource;
|
||||
}
|
||||
}
|
||||
+137
-133
@@ -38,153 +38,157 @@ import java.util.List;
|
||||
* @author zhangsen
|
||||
*/
|
||||
@LoadLevel(name = "db", scope = Scope.PROTOTYPE)
|
||||
public class DataBaseSessionManager extends AbstractSessionManager
|
||||
implements Initialize {
|
||||
public class DataBaseSessionManager extends AbstractSessionManager implements Initialize {
|
||||
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(DataBaseSessionManager.class);
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(DataBaseSessionManager.class);
|
||||
|
||||
/**
|
||||
* The Task name.
|
||||
*/
|
||||
protected String taskName;
|
||||
/**
|
||||
* The Task name.
|
||||
*/
|
||||
protected String taskName;
|
||||
|
||||
/**
|
||||
* Instantiates a new Data base session manager.
|
||||
*/
|
||||
public DataBaseSessionManager() {
|
||||
super();
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Data base session manager.
|
||||
*/
|
||||
public DataBaseSessionManager() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Data base session manager.
|
||||
*
|
||||
* @param name the name
|
||||
*/
|
||||
public DataBaseSessionManager(String name) {
|
||||
super();
|
||||
this.taskName = name;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Data base session manager.
|
||||
* @param name the name
|
||||
*/
|
||||
public DataBaseSessionManager(String name) {
|
||||
super();
|
||||
this.taskName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
transactionStoreManager = DataBaseTransactionStoreManager.getInstance();
|
||||
}
|
||||
@Override
|
||||
public void init() {
|
||||
transactionStoreManager = DataBaseTransactionStoreManager.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (StringUtils.isBlank(taskName)) {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_ADD, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addGlobalSession failed.");
|
||||
}
|
||||
} else {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (StringUtils.isBlank(taskName)) {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_ADD, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {
|
||||
if (StringUtils.isNotBlank(taskName)) {
|
||||
return;
|
||||
}
|
||||
session.setStatus(status);
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("updateGlobalSessionStatus failed.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {
|
||||
if (StringUtils.isNotBlank(taskName)) {
|
||||
return;
|
||||
}
|
||||
session.setStatus(status);
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("updateGlobalSessionStatus failed.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove globalSession
|
||||
* 1. rootSessionManager remove normal globalSession
|
||||
* 2. retryCommitSessionManager and retryRollbackSessionManager remove retry expired globalSession
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_REMOVE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("removeGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* remove globalSession 1. rootSessionManager remove normal globalSession 2.
|
||||
* retryCommitSessionManager and retryRollbackSessionManager remove retry expired
|
||||
* globalSession
|
||||
* @param session the session
|
||||
* @throws TransactionException the transaction exception
|
||||
*/
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_REMOVE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("removeGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
|
||||
if (StringUtils.isNotBlank(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_ADD, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addBranchSession failed.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void addBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
|
||||
if (StringUtils.isNotBlank(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_ADD, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addBranchSession failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBranchSessionStatus(BranchSession session, BranchStatus status) throws TransactionException {
|
||||
if (StringUtils.isNotBlank(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("updateBranchSessionStatus failed.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateBranchSessionStatus(BranchSession session, BranchStatus status) throws TransactionException {
|
||||
if (StringUtils.isNotBlank(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("updateBranchSessionStatus failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
|
||||
if (StringUtils.isNotBlank(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_REMOVE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("removeBranchSession failed.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void removeBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
|
||||
if (StringUtils.isNotBlank(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_REMOVE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("removeBranchSession failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid) {
|
||||
return this.findGlobalSession(xid, true);
|
||||
}
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid) {
|
||||
return this.findGlobalSession(xid, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid, boolean withBranchSessions) {
|
||||
return transactionStoreManager.readSession(xid, withBranchSessions);
|
||||
}
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid, boolean withBranchSessions) {
|
||||
return transactionStoreManager.readSession(xid, withBranchSessions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<GlobalSession> allSessions() {
|
||||
// get by taskName
|
||||
if (SessionHolder.ASYNC_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.AsyncCommitting));
|
||||
} else if (SessionHolder.RETRY_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.CommitRetrying, GlobalStatus.Committing));
|
||||
} else if (SessionHolder.RETRY_ROLLBACKING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.RollbackRetrying, GlobalStatus.Rollbacking,
|
||||
GlobalStatus.TimeoutRollbacking, GlobalStatus.TimeoutRollbackRetrying));
|
||||
} else {
|
||||
// all data
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.UnKnown, GlobalStatus.Begin, GlobalStatus.Committing,
|
||||
GlobalStatus.CommitRetrying, GlobalStatus.Rollbacking, GlobalStatus.RollbackRetrying, GlobalStatus.TimeoutRollbacking,
|
||||
GlobalStatus.TimeoutRollbackRetrying, GlobalStatus.AsyncCommitting));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Collection<GlobalSession> allSessions() {
|
||||
// get by taskName
|
||||
if (SessionHolder.ASYNC_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.AsyncCommitting));
|
||||
}
|
||||
else if (SessionHolder.RETRY_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.CommitRetrying, GlobalStatus.Committing));
|
||||
}
|
||||
else if (SessionHolder.RETRY_ROLLBACKING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.RollbackRetrying, GlobalStatus.Rollbacking,
|
||||
GlobalStatus.TimeoutRollbacking, GlobalStatus.TimeoutRollbackRetrying));
|
||||
}
|
||||
else {
|
||||
// all data
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.UnKnown, GlobalStatus.Begin,
|
||||
GlobalStatus.Committing, GlobalStatus.CommitRetrying, GlobalStatus.Rollbacking,
|
||||
GlobalStatus.RollbackRetrying, GlobalStatus.TimeoutRollbacking,
|
||||
GlobalStatus.TimeoutRollbackRetrying, GlobalStatus.AsyncCommitting));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> findGlobalSessions(SessionCondition condition) {
|
||||
// nothing need to do
|
||||
return transactionStoreManager.readSession(condition);
|
||||
}
|
||||
@Override
|
||||
public List<GlobalSession> findGlobalSessions(SessionCondition condition) {
|
||||
// nothing need to do
|
||||
return transactionStoreManager.readSession(condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException {
|
||||
return lockCallable.call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException {
|
||||
return lockCallable.call();
|
||||
}
|
||||
}
|
||||
+193
-190
@@ -46,211 +46,214 @@ import static io.seata.common.DefaultValues.DEFAULT_QUERY_LIMIT;
|
||||
* @author zhangsen
|
||||
*/
|
||||
public class DataBaseTransactionStoreManager extends AbstractTransactionStoreManager
|
||||
implements TransactionStoreManager {
|
||||
implements TransactionStoreManager {
|
||||
|
||||
private static volatile DataBaseTransactionStoreManager instance;
|
||||
private static volatile DataBaseTransactionStoreManager instance;
|
||||
|
||||
/**
|
||||
* The constant CONFIG.
|
||||
*/
|
||||
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
/**
|
||||
* The constant CONFIG.
|
||||
*/
|
||||
protected static final Configuration CONFIG = ConfigurationFactory.getInstance();
|
||||
|
||||
/**
|
||||
* The Log store.
|
||||
*/
|
||||
protected LogStore logStore;
|
||||
/**
|
||||
* The Log store.
|
||||
*/
|
||||
protected LogStore logStore;
|
||||
|
||||
/**
|
||||
* The Log query limit.
|
||||
*/
|
||||
protected int logQueryLimit;
|
||||
/**
|
||||
* The Log query limit.
|
||||
*/
|
||||
protected int logQueryLimit;
|
||||
|
||||
/**
|
||||
* Get the instance.
|
||||
*/
|
||||
public static DataBaseTransactionStoreManager getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (DataBaseTransactionStoreManager.class) {
|
||||
if (instance == null) {
|
||||
instance = new DataBaseTransactionStoreManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
/**
|
||||
* Get the instance.
|
||||
*/
|
||||
public static DataBaseTransactionStoreManager getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (DataBaseTransactionStoreManager.class) {
|
||||
if (instance == null) {
|
||||
instance = new DataBaseTransactionStoreManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Database transaction store manager.
|
||||
*/
|
||||
private DataBaseTransactionStoreManager() {
|
||||
logQueryLimit = CONFIG.getInt(ConfigurationKeys.STORE_DB_LOG_QUERY_LIMIT, DEFAULT_QUERY_LIMIT);
|
||||
String datasourceType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
//init dataSource
|
||||
DataSource logStoreDataSource = EnhancedServiceLoader.load(DataSourceProvider.class, datasourceType).provide();
|
||||
logStore = new LogStoreDataBaseDAO(logStoreDataSource);
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Database transaction store manager.
|
||||
*/
|
||||
private DataBaseTransactionStoreManager() {
|
||||
logQueryLimit = CONFIG.getInt(ConfigurationKeys.STORE_DB_LOG_QUERY_LIMIT, DEFAULT_QUERY_LIMIT);
|
||||
String datasourceType = CONFIG.getConfig(ConfigurationKeys.STORE_DB_DATASOURCE_TYPE);
|
||||
// init dataSource
|
||||
DataSource logStoreDataSource = EnhancedServiceLoader.load(DataSourceProvider.class, datasourceType).provide();
|
||||
logStore = new LogStoreDataBaseDAO(logStoreDataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean writeSession(LogOperation logOperation, SessionStorable session) {
|
||||
if (LogOperation.GLOBAL_ADD.equals(logOperation)) {
|
||||
return logStore.insertGlobalTransactionDO(SessionConverter.convertGlobalTransactionDO(session));
|
||||
} else if (LogOperation.GLOBAL_UPDATE.equals(logOperation)) {
|
||||
return logStore.updateGlobalTransactionDO(SessionConverter.convertGlobalTransactionDO(session));
|
||||
} else if (LogOperation.GLOBAL_REMOVE.equals(logOperation)) {
|
||||
return logStore.deleteGlobalTransactionDO(SessionConverter.convertGlobalTransactionDO(session));
|
||||
} else if (LogOperation.BRANCH_ADD.equals(logOperation)) {
|
||||
return logStore.insertBranchTransactionDO(SessionConverter.convertBranchTransactionDO(session));
|
||||
} else if (LogOperation.BRANCH_UPDATE.equals(logOperation)) {
|
||||
return logStore.updateBranchTransactionDO(SessionConverter.convertBranchTransactionDO(session));
|
||||
} else if (LogOperation.BRANCH_REMOVE.equals(logOperation)) {
|
||||
return logStore.deleteBranchTransactionDO(SessionConverter.convertBranchTransactionDO(session));
|
||||
} else {
|
||||
throw new StoreException("Unknown LogOperation:" + logOperation.name());
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean writeSession(LogOperation logOperation, SessionStorable session) {
|
||||
if (LogOperation.GLOBAL_ADD.equals(logOperation)) {
|
||||
return logStore.insertGlobalTransactionDO(SessionConverter.convertGlobalTransactionDO(session));
|
||||
}
|
||||
else if (LogOperation.GLOBAL_UPDATE.equals(logOperation)) {
|
||||
return logStore.updateGlobalTransactionDO(SessionConverter.convertGlobalTransactionDO(session));
|
||||
}
|
||||
else if (LogOperation.GLOBAL_REMOVE.equals(logOperation)) {
|
||||
return logStore.deleteGlobalTransactionDO(SessionConverter.convertGlobalTransactionDO(session));
|
||||
}
|
||||
else if (LogOperation.BRANCH_ADD.equals(logOperation)) {
|
||||
return logStore.insertBranchTransactionDO(SessionConverter.convertBranchTransactionDO(session));
|
||||
}
|
||||
else if (LogOperation.BRANCH_UPDATE.equals(logOperation)) {
|
||||
return logStore.updateBranchTransactionDO(SessionConverter.convertBranchTransactionDO(session));
|
||||
}
|
||||
else if (LogOperation.BRANCH_REMOVE.equals(logOperation)) {
|
||||
return logStore.deleteBranchTransactionDO(SessionConverter.convertBranchTransactionDO(session));
|
||||
}
|
||||
else {
|
||||
throw new StoreException("Unknown LogOperation:" + logOperation.name());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read session global session.
|
||||
*
|
||||
* @param transactionId the transaction id
|
||||
* @return the global session
|
||||
*/
|
||||
public GlobalSession readSession(Long transactionId) {
|
||||
//global transaction
|
||||
GlobalTransactionDO globalTransactionDO = logStore.queryGlobalTransactionDO(transactionId);
|
||||
if (globalTransactionDO == null) {
|
||||
return null;
|
||||
}
|
||||
//branch transactions
|
||||
List<BranchTransactionDO> branchTransactionDOs = logStore.queryBranchTransactionDO(
|
||||
globalTransactionDO.getXid());
|
||||
return getGlobalSession(globalTransactionDO, branchTransactionDOs);
|
||||
}
|
||||
/**
|
||||
* Read session global session.
|
||||
* @param transactionId the transaction id
|
||||
* @return the global session
|
||||
*/
|
||||
public GlobalSession readSession(Long transactionId) {
|
||||
// global transaction
|
||||
GlobalTransactionDO globalTransactionDO = logStore.queryGlobalTransactionDO(transactionId);
|
||||
if (globalTransactionDO == null) {
|
||||
return null;
|
||||
}
|
||||
// branch transactions
|
||||
List<BranchTransactionDO> branchTransactionDOs = logStore
|
||||
.queryBranchTransactionDO(globalTransactionDO.getXid());
|
||||
return getGlobalSession(globalTransactionDO, branchTransactionDOs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read session global session.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @return the global session
|
||||
*/
|
||||
@Override
|
||||
public GlobalSession readSession(String xid) {
|
||||
return this.readSession(xid, true);
|
||||
}
|
||||
/**
|
||||
* Read session global session.
|
||||
* @param xid the xid
|
||||
* @return the global session
|
||||
*/
|
||||
@Override
|
||||
public GlobalSession readSession(String xid) {
|
||||
return this.readSession(xid, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read session global session.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
@Override
|
||||
public GlobalSession readSession(String xid, boolean withBranchSessions) {
|
||||
//global transaction
|
||||
GlobalTransactionDO globalTransactionDO = logStore.queryGlobalTransactionDO(xid);
|
||||
if (globalTransactionDO == null) {
|
||||
return null;
|
||||
}
|
||||
//branch transactions
|
||||
List<BranchTransactionDO> branchTransactionDOs = null;
|
||||
//reduce rpc with db when branchRegister and getGlobalStatus
|
||||
if (withBranchSessions) {
|
||||
branchTransactionDOs = logStore.queryBranchTransactionDO(globalTransactionDO.getXid());
|
||||
}
|
||||
return getGlobalSession(globalTransactionDO, branchTransactionDOs);
|
||||
}
|
||||
/**
|
||||
* Read session global session.
|
||||
* @param xid the xid
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
@Override
|
||||
public GlobalSession readSession(String xid, boolean withBranchSessions) {
|
||||
// global transaction
|
||||
GlobalTransactionDO globalTransactionDO = logStore.queryGlobalTransactionDO(xid);
|
||||
if (globalTransactionDO == null) {
|
||||
return null;
|
||||
}
|
||||
// branch transactions
|
||||
List<BranchTransactionDO> branchTransactionDOs = null;
|
||||
// reduce rpc with db when branchRegister and getGlobalStatus
|
||||
if (withBranchSessions) {
|
||||
branchTransactionDOs = logStore.queryBranchTransactionDO(globalTransactionDO.getXid());
|
||||
}
|
||||
return getGlobalSession(globalTransactionDO, branchTransactionDOs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> readSortByTimeoutBeginSessions(boolean withBranchSessions) {
|
||||
return readSession(new GlobalStatus[] {GlobalStatus.Begin}, withBranchSessions);
|
||||
}
|
||||
@Override
|
||||
public List<GlobalSession> readSortByTimeoutBeginSessions(boolean withBranchSessions) {
|
||||
return readSession(new GlobalStatus[] { GlobalStatus.Begin }, withBranchSessions);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read session list.
|
||||
*
|
||||
* @param statuses the statuses
|
||||
* @return the list
|
||||
*/
|
||||
@Override
|
||||
public List<GlobalSession> readSession(GlobalStatus[] statuses, boolean withBranchSessions) {
|
||||
int[] states = new int[statuses.length];
|
||||
for (int i = 0; i < statuses.length; i++) {
|
||||
states[i] = statuses[i].getCode();
|
||||
}
|
||||
//global transaction
|
||||
List<GlobalTransactionDO> globalTransactionDOs = logStore.queryGlobalTransactionDO(states, logQueryLimit);
|
||||
Map<String, List<BranchTransactionDO>> branchTransactionDOsMap = Collections.emptyMap();
|
||||
if (CollectionUtils.isNotEmpty(globalTransactionDOs)) {
|
||||
List<String> xids =
|
||||
globalTransactionDOs.stream().map(GlobalTransactionDO::getXid).collect(Collectors.toList());
|
||||
if (withBranchSessions) {
|
||||
List<BranchTransactionDO> branchTransactionDOs = logStore.queryBranchTransactionDO(xids);
|
||||
branchTransactionDOsMap = branchTransactionDOs.stream().collect(
|
||||
Collectors.groupingBy(BranchTransactionDO::getXid, LinkedHashMap::new, Collectors.toList()));
|
||||
}
|
||||
}
|
||||
Map<String, List<BranchTransactionDO>> finalBranchTransactionDOsMap = branchTransactionDOsMap;
|
||||
return globalTransactionDOs.stream()
|
||||
.map(globalTransactionDO -> getGlobalSession(globalTransactionDO,
|
||||
finalBranchTransactionDOsMap.get(globalTransactionDO.getXid()), withBranchSessions))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
/**
|
||||
* Read session list.
|
||||
* @param statuses the statuses
|
||||
* @return the list
|
||||
*/
|
||||
@Override
|
||||
public List<GlobalSession> readSession(GlobalStatus[] statuses, boolean withBranchSessions) {
|
||||
int[] states = new int[statuses.length];
|
||||
for (int i = 0; i < statuses.length; i++) {
|
||||
states[i] = statuses[i].getCode();
|
||||
}
|
||||
// global transaction
|
||||
List<GlobalTransactionDO> globalTransactionDOs = logStore.queryGlobalTransactionDO(states, logQueryLimit);
|
||||
Map<String, List<BranchTransactionDO>> branchTransactionDOsMap = Collections.emptyMap();
|
||||
if (CollectionUtils.isNotEmpty(globalTransactionDOs)) {
|
||||
List<String> xids = globalTransactionDOs.stream().map(GlobalTransactionDO::getXid)
|
||||
.collect(Collectors.toList());
|
||||
if (withBranchSessions) {
|
||||
List<BranchTransactionDO> branchTransactionDOs = logStore.queryBranchTransactionDO(xids);
|
||||
branchTransactionDOsMap = branchTransactionDOs.stream().collect(
|
||||
Collectors.groupingBy(BranchTransactionDO::getXid, LinkedHashMap::new, Collectors.toList()));
|
||||
}
|
||||
}
|
||||
Map<String, List<BranchTransactionDO>> finalBranchTransactionDOsMap = branchTransactionDOsMap;
|
||||
return globalTransactionDOs.stream()
|
||||
.map(globalTransactionDO -> getGlobalSession(globalTransactionDO,
|
||||
finalBranchTransactionDOsMap.get(globalTransactionDO.getXid()), withBranchSessions))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> readSession(SessionCondition sessionCondition) {
|
||||
if (StringUtils.isNotBlank(sessionCondition.getXid())) {
|
||||
GlobalSession globalSession = readSession(sessionCondition.getXid());
|
||||
if (globalSession != null) {
|
||||
List<GlobalSession> globalSessions = new ArrayList<>();
|
||||
globalSessions.add(globalSession);
|
||||
return globalSessions;
|
||||
}
|
||||
} else if (sessionCondition.getTransactionId() != null) {
|
||||
GlobalSession globalSession = readSession(sessionCondition.getTransactionId());
|
||||
if (globalSession != null) {
|
||||
List<GlobalSession> globalSessions = new ArrayList<>();
|
||||
globalSessions.add(globalSession);
|
||||
return globalSessions;
|
||||
}
|
||||
} else if (CollectionUtils.isNotEmpty(sessionCondition.getStatuses())) {
|
||||
return readSession(sessionCondition.getStatuses(), !sessionCondition.isLazyLoadBranch());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public List<GlobalSession> readSession(SessionCondition sessionCondition) {
|
||||
if (StringUtils.isNotBlank(sessionCondition.getXid())) {
|
||||
GlobalSession globalSession = readSession(sessionCondition.getXid());
|
||||
if (globalSession != null) {
|
||||
List<GlobalSession> globalSessions = new ArrayList<>();
|
||||
globalSessions.add(globalSession);
|
||||
return globalSessions;
|
||||
}
|
||||
}
|
||||
else if (sessionCondition.getTransactionId() != null) {
|
||||
GlobalSession globalSession = readSession(sessionCondition.getTransactionId());
|
||||
if (globalSession != null) {
|
||||
List<GlobalSession> globalSessions = new ArrayList<>();
|
||||
globalSessions.add(globalSession);
|
||||
return globalSessions;
|
||||
}
|
||||
}
|
||||
else if (CollectionUtils.isNotEmpty(sessionCondition.getStatuses())) {
|
||||
return readSession(sessionCondition.getStatuses(), !sessionCondition.isLazyLoadBranch());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private GlobalSession getGlobalSession(GlobalTransactionDO globalTransactionDO,
|
||||
List<BranchTransactionDO> branchTransactionDOs) {
|
||||
return getGlobalSession(globalTransactionDO, branchTransactionDOs, true);
|
||||
}
|
||||
private GlobalSession getGlobalSession(GlobalTransactionDO globalTransactionDO,
|
||||
List<BranchTransactionDO> branchTransactionDOs) {
|
||||
return getGlobalSession(globalTransactionDO, branchTransactionDOs, true);
|
||||
}
|
||||
|
||||
private GlobalSession getGlobalSession(GlobalTransactionDO globalTransactionDO,
|
||||
List<BranchTransactionDO> branchTransactionDOs, boolean withBranchSessions) {
|
||||
GlobalSession globalSession = SessionConverter.convertGlobalSession(globalTransactionDO, !withBranchSessions);
|
||||
// branch transactions
|
||||
if (CollectionUtils.isNotEmpty(branchTransactionDOs)) {
|
||||
for (BranchTransactionDO branchTransactionDO : branchTransactionDOs) {
|
||||
globalSession.add(SessionConverter.convertBranchSession(branchTransactionDO));
|
||||
}
|
||||
}
|
||||
return globalSession;
|
||||
}
|
||||
private GlobalSession getGlobalSession(GlobalTransactionDO globalTransactionDO,
|
||||
List<BranchTransactionDO> branchTransactionDOs, boolean withBranchSessions) {
|
||||
GlobalSession globalSession = SessionConverter.convertGlobalSession(globalTransactionDO, !withBranchSessions);
|
||||
// branch transactions
|
||||
if (CollectionUtils.isNotEmpty(branchTransactionDOs)) {
|
||||
for (BranchTransactionDO branchTransactionDO : branchTransactionDOs) {
|
||||
globalSession.add(SessionConverter.convertBranchSession(branchTransactionDO));
|
||||
}
|
||||
}
|
||||
return globalSession;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets log store.
|
||||
*
|
||||
* @param logStore the log store
|
||||
*/
|
||||
public void setLogStore(LogStore logStore) {
|
||||
this.logStore = logStore;
|
||||
}
|
||||
/**
|
||||
* Sets log store.
|
||||
* @param logStore the log store
|
||||
*/
|
||||
public void setLogStore(LogStore logStore) {
|
||||
this.logStore = logStore;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets log query limit.
|
||||
* @param logQueryLimit the log query limit
|
||||
*/
|
||||
public void setLogQueryLimit(int logQueryLimit) {
|
||||
this.logQueryLimit = logQueryLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets log query limit.
|
||||
*
|
||||
* @param logQueryLimit the log query limit
|
||||
*/
|
||||
public void setLogQueryLimit(int logQueryLimit) {
|
||||
this.logQueryLimit = logQueryLimit;
|
||||
}
|
||||
}
|
||||
+538
-508
File diff suppressed because it is too large.
Load diff
+20
-18
@@ -19,25 +19,27 @@ package io.seata.server.storage.file;
|
||||
* @author lizhao
|
||||
*/
|
||||
public enum FlushDiskMode {
|
||||
/**
|
||||
* sync flush disk
|
||||
*/
|
||||
SYNC_MODEL("sync"),
|
||||
/**
|
||||
* async flush disk
|
||||
*/
|
||||
ASYNC_MODEL("async");
|
||||
|
||||
private String modeStr;
|
||||
/**
|
||||
* sync flush disk
|
||||
*/
|
||||
SYNC_MODEL("sync"),
|
||||
/**
|
||||
* async flush disk
|
||||
*/
|
||||
ASYNC_MODEL("async");
|
||||
|
||||
FlushDiskMode(String modeStr) {
|
||||
this.modeStr = modeStr;
|
||||
}
|
||||
private String modeStr;
|
||||
|
||||
FlushDiskMode(String modeStr) {
|
||||
this.modeStr = modeStr;
|
||||
}
|
||||
|
||||
public static FlushDiskMode findDiskMode(String modeStr) {
|
||||
if (SYNC_MODEL.modeStr.equals(modeStr)) {
|
||||
return SYNC_MODEL;
|
||||
}
|
||||
return ASYNC_MODEL;
|
||||
}
|
||||
|
||||
public static FlushDiskMode findDiskMode(String modeStr) {
|
||||
if (SYNC_MODEL.modeStr.equals(modeStr)) {
|
||||
return SYNC_MODEL;
|
||||
}
|
||||
return ASYNC_MODEL;
|
||||
}
|
||||
}
|
||||
+13
-16
@@ -24,22 +24,19 @@ import java.util.List;
|
||||
*/
|
||||
public interface ReloadableStore {
|
||||
|
||||
/**
|
||||
* Read write store.
|
||||
*
|
||||
* @param readSize the read size
|
||||
* @param isHistory the is history
|
||||
* @return the list
|
||||
*/
|
||||
List<TransactionWriteStore> readWriteStore(int readSize, boolean isHistory);
|
||||
|
||||
/**
|
||||
* Has remaining boolean.
|
||||
*
|
||||
* @param isHistory the is history
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean hasRemaining(boolean isHistory);
|
||||
/**
|
||||
* Read write store.
|
||||
* @param readSize the read size
|
||||
* @param isHistory the is history
|
||||
* @return the list
|
||||
*/
|
||||
List<TransactionWriteStore> readWriteStore(int readSize, boolean isHistory);
|
||||
|
||||
/**
|
||||
* Has remaining boolean.
|
||||
* @param isHistory the is history
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean hasRemaining(boolean isHistory);
|
||||
|
||||
}
|
||||
+87
-88
@@ -29,101 +29,100 @@ import java.nio.ByteBuffer;
|
||||
* @author slievrly
|
||||
*/
|
||||
public class TransactionWriteStore implements SessionStorable {
|
||||
private SessionStorable sessionRequest;
|
||||
private LogOperation operate;
|
||||
|
||||
/**
|
||||
* Instantiates a new Transaction write store.
|
||||
*
|
||||
* @param sessionRequest the session request
|
||||
* @param operate the operate
|
||||
*/
|
||||
public TransactionWriteStore(SessionStorable sessionRequest, LogOperation operate) {
|
||||
this.sessionRequest = sessionRequest;
|
||||
this.operate = operate;
|
||||
}
|
||||
private SessionStorable sessionRequest;
|
||||
|
||||
/**
|
||||
* Instantiates a new Transaction write store.
|
||||
*/
|
||||
public TransactionWriteStore() {}
|
||||
private LogOperation operate;
|
||||
|
||||
/**
|
||||
* Gets session request.
|
||||
*
|
||||
* @return the session request
|
||||
*/
|
||||
public SessionStorable getSessionRequest() {
|
||||
return sessionRequest;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Transaction write store.
|
||||
* @param sessionRequest the session request
|
||||
* @param operate the operate
|
||||
*/
|
||||
public TransactionWriteStore(SessionStorable sessionRequest, LogOperation operate) {
|
||||
this.sessionRequest = sessionRequest;
|
||||
this.operate = operate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets session request.
|
||||
*
|
||||
* @param sessionRequest the session request
|
||||
*/
|
||||
public void setSessionRequest(SessionStorable sessionRequest) {
|
||||
this.sessionRequest = sessionRequest;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Transaction write store.
|
||||
*/
|
||||
public TransactionWriteStore() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets operate.
|
||||
*
|
||||
* @return the operate
|
||||
*/
|
||||
public LogOperation getOperate() {
|
||||
return operate;
|
||||
}
|
||||
/**
|
||||
* Gets session request.
|
||||
* @return the session request
|
||||
*/
|
||||
public SessionStorable getSessionRequest() {
|
||||
return sessionRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets operate.
|
||||
*
|
||||
* @param operate the operate
|
||||
*/
|
||||
public void setOperate(LogOperation operate) {
|
||||
this.operate = operate;
|
||||
}
|
||||
/**
|
||||
* Sets session request.
|
||||
* @param sessionRequest the session request
|
||||
*/
|
||||
public void setSessionRequest(SessionStorable sessionRequest) {
|
||||
this.sessionRequest = sessionRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
byte[] bySessionRequest = this.sessionRequest.encode();
|
||||
byte byOpCode = this.getOperate().getCode();
|
||||
int len = bySessionRequest.length + 1;
|
||||
byte[] byResult = new byte[len];
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(byResult);
|
||||
byteBuffer.put(bySessionRequest);
|
||||
byteBuffer.put(byOpCode);
|
||||
return byResult;
|
||||
}
|
||||
/**
|
||||
* Gets operate.
|
||||
* @return the operate
|
||||
*/
|
||||
public LogOperation getOperate() {
|
||||
return operate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] src) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(src);
|
||||
byte[] bySessionRequest = new byte[src.length - 1];
|
||||
byteBuffer.get(bySessionRequest);
|
||||
byte byOpCode = byteBuffer.get();
|
||||
this.operate = LogOperation.getLogOperationByCode(byOpCode);
|
||||
SessionStorable tmpSessionStorable = getSessionInstanceByOperation(this.operate);
|
||||
tmpSessionStorable.decode(bySessionRequest);
|
||||
this.sessionRequest = tmpSessionStorable;
|
||||
}
|
||||
/**
|
||||
* Sets operate.
|
||||
* @param operate the operate
|
||||
*/
|
||||
public void setOperate(LogOperation operate) {
|
||||
this.operate = operate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
byte[] bySessionRequest = this.sessionRequest.encode();
|
||||
byte byOpCode = this.getOperate().getCode();
|
||||
int len = bySessionRequest.length + 1;
|
||||
byte[] byResult = new byte[len];
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(byResult);
|
||||
byteBuffer.put(bySessionRequest);
|
||||
byteBuffer.put(byOpCode);
|
||||
return byResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] src) {
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(src);
|
||||
byte[] bySessionRequest = new byte[src.length - 1];
|
||||
byteBuffer.get(bySessionRequest);
|
||||
byte byOpCode = byteBuffer.get();
|
||||
this.operate = LogOperation.getLogOperationByCode(byOpCode);
|
||||
SessionStorable tmpSessionStorable = getSessionInstanceByOperation(this.operate);
|
||||
tmpSessionStorable.decode(bySessionRequest);
|
||||
this.sessionRequest = tmpSessionStorable;
|
||||
}
|
||||
|
||||
private SessionStorable getSessionInstanceByOperation(LogOperation logOperation) {
|
||||
SessionStorable sessionStorable = null;
|
||||
switch (logOperation) {
|
||||
case GLOBAL_ADD:
|
||||
case GLOBAL_UPDATE:
|
||||
case GLOBAL_REMOVE:
|
||||
sessionStorable = new GlobalSession();
|
||||
break;
|
||||
case BRANCH_ADD:
|
||||
case BRANCH_UPDATE:
|
||||
case BRANCH_REMOVE:
|
||||
sessionStorable = new BranchSession();
|
||||
break;
|
||||
default:
|
||||
throw new ShouldNeverHappenException("incorrect logOperation");
|
||||
}
|
||||
return sessionStorable;
|
||||
}
|
||||
|
||||
private SessionStorable getSessionInstanceByOperation(LogOperation logOperation) {
|
||||
SessionStorable sessionStorable = null;
|
||||
switch (logOperation) {
|
||||
case GLOBAL_ADD:
|
||||
case GLOBAL_UPDATE:
|
||||
case GLOBAL_REMOVE:
|
||||
sessionStorable = new GlobalSession();
|
||||
break;
|
||||
case BRANCH_ADD:
|
||||
case BRANCH_UPDATE:
|
||||
case BRANCH_REMOVE:
|
||||
sessionStorable = new BranchSession();
|
||||
break;
|
||||
default:
|
||||
throw new ShouldNeverHappenException("incorrect logOperation");
|
||||
}
|
||||
return sessionStorable;
|
||||
}
|
||||
}
|
||||
+21
-20
@@ -35,26 +35,27 @@ import static io.seata.core.context.RootContext.MDC_KEY_BRANCH_ID;
|
||||
@LoadLevel(name = "file")
|
||||
public class FileLockManager extends AbstractLockManager {
|
||||
|
||||
@Override
|
||||
public Locker getLocker(BranchSession branchSession) {
|
||||
return new FileLocker(branchSession);
|
||||
}
|
||||
@Override
|
||||
public Locker getLocker(BranchSession branchSession) {
|
||||
return new FileLocker(branchSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException {
|
||||
List<BranchSession> branchSessions = globalSession.getBranchSessions();
|
||||
boolean releaseLockResult = true;
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
try {
|
||||
MDC.put(MDC_KEY_BRANCH_ID, String.valueOf(branchSession.getBranchId()));
|
||||
if (!this.releaseLock(branchSession)) {
|
||||
releaseLockResult = false;
|
||||
}
|
||||
} finally {
|
||||
MDC.remove(MDC_KEY_BRANCH_ID);
|
||||
}
|
||||
}
|
||||
return releaseLockResult;
|
||||
}
|
||||
@Override
|
||||
public boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException {
|
||||
List<BranchSession> branchSessions = globalSession.getBranchSessions();
|
||||
boolean releaseLockResult = true;
|
||||
for (BranchSession branchSession : branchSessions) {
|
||||
try {
|
||||
MDC.put(MDC_KEY_BRANCH_ID, String.valueOf(branchSession.getBranchId()));
|
||||
if (!this.releaseLock(branchSession)) {
|
||||
releaseLockResult = false;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
MDC.remove(MDC_KEY_BRANCH_ID);
|
||||
}
|
||||
}
|
||||
return releaseLockResult;
|
||||
}
|
||||
|
||||
}
|
||||
+168
-160
@@ -40,181 +40,189 @@ import static io.seata.core.exception.TransactionExceptionCode.LockKeyConflictFa
|
||||
*/
|
||||
public class FileLocker extends AbstractLocker {
|
||||
|
||||
private static final int BUCKET_PER_TABLE = 128;
|
||||
private static final int BUCKET_PER_TABLE = 128;
|
||||
|
||||
private static final ConcurrentMap<String/* resourceId */, ConcurrentMap<String/* tableName */,
|
||||
ConcurrentMap<Integer/* bucketId */, BucketLockMap>>>
|
||||
LOCK_MAP = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentMap<String/* resourceId */, ConcurrentMap<String/*
|
||||
* tableName
|
||||
*/, ConcurrentMap<Integer/*
|
||||
* bucketId
|
||||
*/, BucketLockMap>>> LOCK_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
/**
|
||||
* The Branch session.
|
||||
*/
|
||||
protected BranchSession branchSession;
|
||||
/**
|
||||
* The Branch session.
|
||||
*/
|
||||
protected BranchSession branchSession;
|
||||
|
||||
/**
|
||||
* Instantiates a new Memory locker.
|
||||
*
|
||||
* @param branchSession the branch session
|
||||
*/
|
||||
public FileLocker(BranchSession branchSession) {
|
||||
this.branchSession = branchSession;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Memory locker.
|
||||
* @param branchSession the branch session
|
||||
*/
|
||||
public FileLocker(BranchSession branchSession) {
|
||||
this.branchSession = branchSession;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> rowLocks) {
|
||||
return acquireLock(rowLocks, true, false);
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> rowLocks) {
|
||||
return acquireLock(rowLocks, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> rowLocks, boolean autoCommit, boolean skipCheckLock) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
String resourceId = branchSession.getResourceId();
|
||||
long transactionId = branchSession.getTransactionId();
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> rowLocks, boolean autoCommit, boolean skipCheckLock) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
String resourceId = branchSession.getResourceId();
|
||||
long transactionId = branchSession.getTransactionId();
|
||||
|
||||
ConcurrentMap<BucketLockMap, Set<String>> bucketHolder = branchSession.getLockHolder();
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, BucketLockMap>> dbLockMap = CollectionUtils.computeIfAbsent(
|
||||
LOCK_MAP, resourceId, key -> new ConcurrentHashMap<>());
|
||||
boolean failFast = false;
|
||||
boolean canLock = true;
|
||||
for (RowLock lock : rowLocks) {
|
||||
String tableName = lock.getTableName();
|
||||
String pk = lock.getPk();
|
||||
ConcurrentMap<Integer, BucketLockMap> tableLockMap = CollectionUtils.computeIfAbsent(dbLockMap, tableName,
|
||||
key -> new ConcurrentHashMap<>());
|
||||
ConcurrentMap<BucketLockMap, Set<String>> bucketHolder = branchSession.getLockHolder();
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, BucketLockMap>> dbLockMap = CollectionUtils
|
||||
.computeIfAbsent(LOCK_MAP, resourceId, key -> new ConcurrentHashMap<>());
|
||||
boolean failFast = false;
|
||||
boolean canLock = true;
|
||||
for (RowLock lock : rowLocks) {
|
||||
String tableName = lock.getTableName();
|
||||
String pk = lock.getPk();
|
||||
ConcurrentMap<Integer, BucketLockMap> tableLockMap = CollectionUtils.computeIfAbsent(dbLockMap, tableName,
|
||||
key -> new ConcurrentHashMap<>());
|
||||
|
||||
int bucketId = pk.hashCode() % BUCKET_PER_TABLE;
|
||||
BucketLockMap bucketLockMap = CollectionUtils.computeIfAbsent(tableLockMap, bucketId,
|
||||
key -> new BucketLockMap());
|
||||
BranchSession previousLockBranchSession = bucketLockMap.get().putIfAbsent(pk, branchSession);
|
||||
if (previousLockBranchSession == null) {
|
||||
// No existing lock, and now locked by myself
|
||||
Set<String> keysInHolder = CollectionUtils.computeIfAbsent(bucketHolder, bucketLockMap,
|
||||
key -> ConcurrentHashMap.newKeySet());
|
||||
keysInHolder.add(pk);
|
||||
} else if (previousLockBranchSession.getTransactionId() == transactionId) {
|
||||
// Locked by me before
|
||||
continue;
|
||||
} else {
|
||||
LOGGER.info("Global lock on [" + tableName + ":" + pk + "] is holding by " + previousLockBranchSession.getBranchId());
|
||||
try {
|
||||
// Release all acquired locks.
|
||||
branchSession.unlock();
|
||||
} catch (TransactionException e) {
|
||||
throw new FrameworkException(e);
|
||||
}
|
||||
if (!autoCommit && previousLockBranchSession.getLockStatus() == LockStatus.Rollbacking) {
|
||||
failFast = true;
|
||||
break;
|
||||
}
|
||||
if (canLock) {
|
||||
canLock = false;
|
||||
if (autoCommit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (failFast) {
|
||||
throw new StoreException(new BranchTransactionException(LockKeyConflictFailFast));
|
||||
}
|
||||
return canLock;
|
||||
}
|
||||
int bucketId = pk.hashCode() % BUCKET_PER_TABLE;
|
||||
BucketLockMap bucketLockMap = CollectionUtils.computeIfAbsent(tableLockMap, bucketId,
|
||||
key -> new BucketLockMap());
|
||||
BranchSession previousLockBranchSession = bucketLockMap.get().putIfAbsent(pk, branchSession);
|
||||
if (previousLockBranchSession == null) {
|
||||
// No existing lock, and now locked by myself
|
||||
Set<String> keysInHolder = CollectionUtils.computeIfAbsent(bucketHolder, bucketLockMap,
|
||||
key -> ConcurrentHashMap.newKeySet());
|
||||
keysInHolder.add(pk);
|
||||
}
|
||||
else if (previousLockBranchSession.getTransactionId() == transactionId) {
|
||||
// Locked by me before
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
LOGGER.info("Global lock on [" + tableName + ":" + pk + "] is holding by "
|
||||
+ previousLockBranchSession.getBranchId());
|
||||
try {
|
||||
// Release all acquired locks.
|
||||
branchSession.unlock();
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
throw new FrameworkException(e);
|
||||
}
|
||||
if (!autoCommit && previousLockBranchSession.getLockStatus() == LockStatus.Rollbacking) {
|
||||
failFast = true;
|
||||
break;
|
||||
}
|
||||
if (canLock) {
|
||||
canLock = false;
|
||||
if (autoCommit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (failFast) {
|
||||
throw new StoreException(new BranchTransactionException(LockKeyConflictFailFast));
|
||||
}
|
||||
return canLock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(List<RowLock> rowLock) {
|
||||
if (CollectionUtils.isEmpty(rowLock)) {
|
||||
//no lock
|
||||
return true;
|
||||
}
|
||||
ConcurrentMap<BucketLockMap, Set<String>> lockHolder = branchSession.getLockHolder();
|
||||
if (CollectionUtils.isEmpty(lockHolder)) {
|
||||
return true;
|
||||
}
|
||||
for (Map.Entry<BucketLockMap, Set<String>> entry : lockHolder.entrySet()) {
|
||||
BucketLockMap bucket = entry.getKey();
|
||||
Set<String> keys = entry.getValue();
|
||||
for (String key : keys) {
|
||||
// remove lock only if it locked by myself
|
||||
bucket.get().remove(key, branchSession);
|
||||
}
|
||||
}
|
||||
lockHolder.clear();
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(List<RowLock> rowLock) {
|
||||
if (CollectionUtils.isEmpty(rowLock)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
ConcurrentMap<BucketLockMap, Set<String>> lockHolder = branchSession.getLockHolder();
|
||||
if (CollectionUtils.isEmpty(lockHolder)) {
|
||||
return true;
|
||||
}
|
||||
for (Map.Entry<BucketLockMap, Set<String>> entry : lockHolder.entrySet()) {
|
||||
BucketLockMap bucket = entry.getKey();
|
||||
Set<String> keys = entry.getValue();
|
||||
for (String key : keys) {
|
||||
// remove lock only if it locked by myself
|
||||
bucket.get().remove(key, branchSession);
|
||||
}
|
||||
}
|
||||
lockHolder.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLockable(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
//no lock
|
||||
return true;
|
||||
}
|
||||
Long transactionId = rowLocks.get(0).getTransactionId();
|
||||
String resourceId = rowLocks.get(0).getResourceId();
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, BucketLockMap>> dbLockMap = LOCK_MAP.get(resourceId);
|
||||
if (dbLockMap == null) {
|
||||
return true;
|
||||
}
|
||||
for (RowLock rowLock : rowLocks) {
|
||||
String tableName = rowLock.getTableName();
|
||||
String pk = rowLock.getPk();
|
||||
@Override
|
||||
public boolean isLockable(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
// no lock
|
||||
return true;
|
||||
}
|
||||
Long transactionId = rowLocks.get(0).getTransactionId();
|
||||
String resourceId = rowLocks.get(0).getResourceId();
|
||||
ConcurrentMap<String, ConcurrentMap<Integer, BucketLockMap>> dbLockMap = LOCK_MAP.get(resourceId);
|
||||
if (dbLockMap == null) {
|
||||
return true;
|
||||
}
|
||||
for (RowLock rowLock : rowLocks) {
|
||||
String tableName = rowLock.getTableName();
|
||||
String pk = rowLock.getPk();
|
||||
|
||||
ConcurrentMap<Integer, BucketLockMap> tableLockMap = dbLockMap.get(tableName);
|
||||
if (tableLockMap == null) {
|
||||
continue;
|
||||
}
|
||||
int bucketId = pk.hashCode() % BUCKET_PER_TABLE;
|
||||
BucketLockMap bucketLockMap = tableLockMap.get(bucketId);
|
||||
if (bucketLockMap == null) {
|
||||
continue;
|
||||
}
|
||||
BranchSession branchSession = bucketLockMap.get().get(pk);
|
||||
Long lockingTransactionId = branchSession != null ? branchSession.getTransactionId() : null;
|
||||
if (lockingTransactionId == null || lockingTransactionId.longValue() == transactionId) {
|
||||
// Locked by me
|
||||
continue;
|
||||
} else {
|
||||
LOGGER.info("Global lock on [" + tableName + ":" + pk + "] is holding by " + lockingTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ConcurrentMap<Integer, BucketLockMap> tableLockMap = dbLockMap.get(tableName);
|
||||
if (tableLockMap == null) {
|
||||
continue;
|
||||
}
|
||||
int bucketId = pk.hashCode() % BUCKET_PER_TABLE;
|
||||
BucketLockMap bucketLockMap = tableLockMap.get(bucketId);
|
||||
if (bucketLockMap == null) {
|
||||
continue;
|
||||
}
|
||||
BranchSession branchSession = bucketLockMap.get().get(pk);
|
||||
Long lockingTransactionId = branchSession != null ? branchSession.getTransactionId() : null;
|
||||
if (lockingTransactionId == null || lockingTransactionId.longValue() == transactionId) {
|
||||
// Locked by me
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
LOGGER.info("Global lock on [" + tableName + ":" + pk + "] is holding by " + lockingTransactionId);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
}
|
||||
@Override
|
||||
public void cleanAllLocks() {
|
||||
LOCK_MAP.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanAllLocks() {
|
||||
LOCK_MAP.clear();
|
||||
}
|
||||
/**
|
||||
* Because bucket lock map will be key of HashMap(lockHolder), however
|
||||
* {@link ConcurrentHashMap} overwrites {@link Object#hashCode()} and
|
||||
* {@link Object#equals(Object)}, that leads to hash key conflict in lockHolder. We
|
||||
* define a {@link BucketLockMap} to hold the ConcurrentHashMap(bucketLockMap) and
|
||||
* replace it as key of HashMap(lockHolder).
|
||||
*/
|
||||
public static class BucketLockMap {
|
||||
|
||||
/**
|
||||
* Because bucket lock map will be key of HashMap(lockHolder), however {@link ConcurrentHashMap} overwrites
|
||||
* {@link Object#hashCode()} and {@link Object#equals(Object)}, that leads to hash key conflict in lockHolder.
|
||||
* We define a {@link BucketLockMap} to hold the ConcurrentHashMap(bucketLockMap) and replace it as key of
|
||||
* HashMap(lockHolder).
|
||||
*/
|
||||
public static class BucketLockMap {
|
||||
private final ConcurrentHashMap<String/* pk */, BranchSession/* branchSession */> bucketLockMap
|
||||
= new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String/* pk */, BranchSession/* branchSession */> bucketLockMap = new ConcurrentHashMap<>();
|
||||
|
||||
ConcurrentHashMap<String, BranchSession> get() {
|
||||
return bucketLockMap;
|
||||
}
|
||||
ConcurrentHashMap<String, BranchSession> get() {
|
||||
return bucketLockMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return super.equals(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
+303
-295
@@ -39,7 +39,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static io.seata.common.DefaultValues.DEFAULT_SERVICE_SESSION_RELOAD_READ_SIZE;
|
||||
|
||||
|
||||
/**
|
||||
* The type File based session manager.
|
||||
*
|
||||
@@ -48,322 +47,331 @@ import static io.seata.common.DefaultValues.DEFAULT_SERVICE_SESSION_RELOAD_READ_
|
||||
@LoadLevel(name = "file", scope = Scope.PROTOTYPE)
|
||||
public class FileSessionManager extends AbstractSessionManager implements Reloadable {
|
||||
|
||||
private static final int READ_SIZE = ConfigurationFactory.getInstance().getInt(
|
||||
ConfigurationKeys.SERVICE_SESSION_RELOAD_READ_SIZE, DEFAULT_SERVICE_SESSION_RELOAD_READ_SIZE);
|
||||
/**
|
||||
* The Session map.
|
||||
*/
|
||||
private Map<String, GlobalSession> sessionMap = new ConcurrentHashMap<>();
|
||||
private static final int READ_SIZE = ConfigurationFactory.getInstance()
|
||||
.getInt(ConfigurationKeys.SERVICE_SESSION_RELOAD_READ_SIZE, DEFAULT_SERVICE_SESSION_RELOAD_READ_SIZE);
|
||||
|
||||
/**
|
||||
* Instantiates a new File based session manager.
|
||||
*
|
||||
* @param name the name
|
||||
* @param sessionStoreFilePath the session store file path
|
||||
* @throws IOException the io exception
|
||||
*/
|
||||
public FileSessionManager(String name, String sessionStoreFilePath) throws IOException {
|
||||
super(name);
|
||||
if (StringUtils.isNotBlank(sessionStoreFilePath)) {
|
||||
transactionStoreManager = new FileTransactionStoreManager(
|
||||
sessionStoreFilePath + File.separator + name, this);
|
||||
} else {
|
||||
transactionStoreManager = new AbstractTransactionStoreManager() {
|
||||
@Override
|
||||
public boolean writeSession(LogOperation logOperation, SessionStorable session) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The Session map.
|
||||
*/
|
||||
private Map<String, GlobalSession> sessionMap = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
restoreSessions();
|
||||
}
|
||||
/**
|
||||
* Instantiates a new File based session manager.
|
||||
* @param name the name
|
||||
* @param sessionStoreFilePath the session store file path
|
||||
* @throws IOException the io exception
|
||||
*/
|
||||
public FileSessionManager(String name, String sessionStoreFilePath) throws IOException {
|
||||
super(name);
|
||||
if (StringUtils.isNotBlank(sessionStoreFilePath)) {
|
||||
transactionStoreManager = new FileTransactionStoreManager(sessionStoreFilePath + File.separator + name,
|
||||
this);
|
||||
}
|
||||
else {
|
||||
transactionStoreManager = new AbstractTransactionStoreManager() {
|
||||
@Override
|
||||
public boolean writeSession(LogOperation logOperation, SessionStorable session) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
CollectionUtils.computeIfAbsent(sessionMap, session.getXid(), k -> {
|
||||
try {
|
||||
super.addGlobalSession(session);
|
||||
} catch (TransactionException e) {
|
||||
LOGGER.error("addGlobalSession fail, msg: {}", e.getMessage());
|
||||
}
|
||||
return session;
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void reload() {
|
||||
restoreSessions();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid) {
|
||||
return sessionMap.get(xid);
|
||||
}
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
CollectionUtils.computeIfAbsent(sessionMap, session.getXid(), k -> {
|
||||
try {
|
||||
super.addGlobalSession(session);
|
||||
}
|
||||
catch (TransactionException e) {
|
||||
LOGGER.error("addGlobalSession fail, msg: {}", e.getMessage());
|
||||
}
|
||||
return session;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid, boolean withBranchSessions) {
|
||||
// withBranchSessions without process in memory
|
||||
return sessionMap.get(xid);
|
||||
}
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid) {
|
||||
return sessionMap.get(xid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (sessionMap.remove(session.getXid()) != null) {
|
||||
super.removeGlobalSession(session);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid, boolean withBranchSessions) {
|
||||
// withBranchSessions without process in memory
|
||||
return sessionMap.get(xid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<GlobalSession> allSessions() {
|
||||
return sessionMap.values();
|
||||
}
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (sessionMap.remove(session.getXid()) != null) {
|
||||
super.removeGlobalSession(session);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> findGlobalSessions(SessionCondition condition) {
|
||||
List<GlobalSession> found = new ArrayList<>();
|
||||
@Override
|
||||
public Collection<GlobalSession> allSessions() {
|
||||
return sessionMap.values();
|
||||
}
|
||||
|
||||
List<GlobalStatus> globalStatuses = null;
|
||||
if (null != condition.getStatuses() && condition.getStatuses().length > 0) {
|
||||
globalStatuses = Arrays.asList(condition.getStatuses());
|
||||
}
|
||||
for (GlobalSession globalSession : sessionMap.values()) {
|
||||
if (null != condition.getOverTimeAliveMills() && condition.getOverTimeAliveMills() > 0) {
|
||||
if (System.currentTimeMillis() - globalSession.getBeginTime() <= condition.getOverTimeAliveMills()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public List<GlobalSession> findGlobalSessions(SessionCondition condition) {
|
||||
List<GlobalSession> found = new ArrayList<>();
|
||||
|
||||
if (!StringUtils.isEmpty(condition.getXid())) {
|
||||
if (Objects.equals(condition.getXid(), globalSession.getXid())) {
|
||||
// Only one will be found, just add and return
|
||||
found.add(globalSession);
|
||||
return found;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
List<GlobalStatus> globalStatuses = null;
|
||||
if (null != condition.getStatuses() && condition.getStatuses().length > 0) {
|
||||
globalStatuses = Arrays.asList(condition.getStatuses());
|
||||
}
|
||||
for (GlobalSession globalSession : sessionMap.values()) {
|
||||
if (null != condition.getOverTimeAliveMills() && condition.getOverTimeAliveMills() > 0) {
|
||||
if (System.currentTimeMillis() - globalSession.getBeginTime() <= condition.getOverTimeAliveMills()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (null != condition.getTransactionId() && condition.getTransactionId() > 0) {
|
||||
if (Objects.equals(condition.getTransactionId(), globalSession.getTransactionId())) {
|
||||
// Only one will be found, just add and return
|
||||
found.add(globalSession);
|
||||
return found;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!StringUtils.isEmpty(condition.getXid())) {
|
||||
if (Objects.equals(condition.getXid(), globalSession.getXid())) {
|
||||
// Only one will be found, just add and return
|
||||
found.add(globalSession);
|
||||
return found;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (null != globalStatuses) {
|
||||
if (!globalStatuses.contains(globalSession.getStatus())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (null != condition.getTransactionId() && condition.getTransactionId() > 0) {
|
||||
if (Objects.equals(condition.getTransactionId(), globalSession.getTransactionId())) {
|
||||
// Only one will be found, just add and return
|
||||
found.add(globalSession);
|
||||
return found;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// All test pass, add to resp
|
||||
found.add(globalSession);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
if (null != globalStatuses) {
|
||||
if (!globalStatuses.contains(globalSession.getStatus())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException {
|
||||
globalSession.lock();
|
||||
try {
|
||||
return lockCallable.call();
|
||||
} finally {
|
||||
globalSession.unlock();
|
||||
}
|
||||
}
|
||||
// All test pass, add to resp
|
||||
found.add(globalSession);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
private void restoreSessions() {
|
||||
final Set<String> removedGlobalBuffer = new HashSet<>();
|
||||
final Map<String, Map<Long, BranchSession>> unhandledBranchBuffer = new HashMap<>();
|
||||
@Override
|
||||
public <T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException {
|
||||
globalSession.lock();
|
||||
try {
|
||||
return lockCallable.call();
|
||||
}
|
||||
finally {
|
||||
globalSession.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
restoreSessions(true, removedGlobalBuffer, unhandledBranchBuffer);
|
||||
restoreSessions(false, removedGlobalBuffer, unhandledBranchBuffer);
|
||||
private void restoreSessions() {
|
||||
final Set<String> removedGlobalBuffer = new HashSet<>();
|
||||
final Map<String, Map<Long, BranchSession>> unhandledBranchBuffer = new HashMap<>();
|
||||
|
||||
if (!unhandledBranchBuffer.isEmpty()) {
|
||||
unhandledBranchBuffer.values().forEach(unhandledBranchSessions -> {
|
||||
unhandledBranchSessions.values().forEach(branchSession -> {
|
||||
String xid = branchSession.getXid();
|
||||
if (removedGlobalBuffer.contains(xid)) {
|
||||
return;
|
||||
}
|
||||
restoreSessions(true, removedGlobalBuffer, unhandledBranchBuffer);
|
||||
restoreSessions(false, removedGlobalBuffer, unhandledBranchBuffer);
|
||||
|
||||
long bid = branchSession.getBranchId();
|
||||
GlobalSession found = sessionMap.get(xid);
|
||||
if (found == null) {
|
||||
// Ignore
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("GlobalSession Does Not Exists For BranchSession [" + bid + "/" + xid + "]");
|
||||
}
|
||||
} else {
|
||||
BranchSession existingBranch = found.getBranch(branchSession.getBranchId());
|
||||
if (existingBranch == null) {
|
||||
found.add(branchSession);
|
||||
} else {
|
||||
existingBranch.setStatus(branchSession.getStatus());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!unhandledBranchBuffer.isEmpty()) {
|
||||
unhandledBranchBuffer.values().forEach(unhandledBranchSessions -> {
|
||||
unhandledBranchSessions.values().forEach(branchSession -> {
|
||||
String xid = branchSession.getXid();
|
||||
if (removedGlobalBuffer.contains(xid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
private boolean checkSessionStatus(GlobalSession globalSession) {
|
||||
GlobalStatus globalStatus = globalSession.getStatus();
|
||||
switch (globalStatus) {
|
||||
case UnKnown:
|
||||
case Committed:
|
||||
case CommitFailed:
|
||||
case Rollbacked:
|
||||
case RollbackFailed:
|
||||
case TimeoutRollbacked:
|
||||
case TimeoutRollbackFailed:
|
||||
case Finished:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
long bid = branchSession.getBranchId();
|
||||
GlobalSession found = sessionMap.get(xid);
|
||||
if (found == null) {
|
||||
// Ignore
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("GlobalSession Does Not Exists For BranchSession [" + bid + "/" + xid + "]");
|
||||
}
|
||||
}
|
||||
else {
|
||||
BranchSession existingBranch = found.getBranch(branchSession.getBranchId());
|
||||
if (existingBranch == null) {
|
||||
found.add(branchSession);
|
||||
}
|
||||
else {
|
||||
existingBranch.setStatus(branchSession.getStatus());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreSessions(boolean isHistory, Set<String> removedGlobalBuffer, Map<String,
|
||||
Map<Long, BranchSession>> unhandledBranchBuffer) {
|
||||
if (!(transactionStoreManager instanceof ReloadableStore)) {
|
||||
return;
|
||||
}
|
||||
while (((ReloadableStore)transactionStoreManager).hasRemaining(isHistory)) {
|
||||
List<TransactionWriteStore> stores = ((ReloadableStore)transactionStoreManager).readWriteStore(READ_SIZE,
|
||||
isHistory);
|
||||
restore(stores, removedGlobalBuffer, unhandledBranchBuffer);
|
||||
}
|
||||
}
|
||||
private boolean checkSessionStatus(GlobalSession globalSession) {
|
||||
GlobalStatus globalStatus = globalSession.getStatus();
|
||||
switch (globalStatus) {
|
||||
case UnKnown:
|
||||
case Committed:
|
||||
case CommitFailed:
|
||||
case Rollbacked:
|
||||
case RollbackFailed:
|
||||
case TimeoutRollbacked:
|
||||
case TimeoutRollbackFailed:
|
||||
case Finished:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private void restore(List<TransactionWriteStore> stores, Set<String> removedGlobalBuffer,
|
||||
Map<String, Map<Long, BranchSession>> unhandledBranchBuffer) {
|
||||
for (TransactionWriteStore store : stores) {
|
||||
TransactionStoreManager.LogOperation logOperation = store.getOperate();
|
||||
SessionStorable sessionStorable = store.getSessionRequest();
|
||||
switch (logOperation) {
|
||||
case GLOBAL_ADD:
|
||||
case GLOBAL_UPDATE: {
|
||||
GlobalSession globalSession = (GlobalSession)sessionStorable;
|
||||
if (globalSession.getTransactionId() == 0) {
|
||||
LOGGER.error(
|
||||
"Restore globalSession from file failed, the transactionId is zero , xid:" + globalSession
|
||||
.getXid());
|
||||
break;
|
||||
}
|
||||
if (removedGlobalBuffer.contains(globalSession.getXid())) {
|
||||
break;
|
||||
}
|
||||
GlobalSession foundGlobalSession = sessionMap.get(globalSession.getXid());
|
||||
if (foundGlobalSession == null) {
|
||||
if (this.checkSessionStatus(globalSession)) {
|
||||
sessionMap.put(globalSession.getXid(), globalSession);
|
||||
} else {
|
||||
removedGlobalBuffer.add(globalSession.getXid());
|
||||
unhandledBranchBuffer.remove(globalSession.getXid());
|
||||
}
|
||||
} else {
|
||||
if (this.checkSessionStatus(globalSession)) {
|
||||
foundGlobalSession.setStatus(globalSession.getStatus());
|
||||
} else {
|
||||
sessionMap.remove(globalSession.getXid());
|
||||
removedGlobalBuffer.add(globalSession.getXid());
|
||||
unhandledBranchBuffer.remove(globalSession.getXid());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GLOBAL_REMOVE: {
|
||||
GlobalSession globalSession = (GlobalSession)sessionStorable;
|
||||
if (globalSession.getTransactionId() == 0) {
|
||||
LOGGER.error(
|
||||
"Restore globalSession from file failed, the transactionId is zero , xid:" + globalSession
|
||||
.getXid());
|
||||
break;
|
||||
}
|
||||
if (removedGlobalBuffer.contains(globalSession.getXid())) {
|
||||
break;
|
||||
}
|
||||
if (sessionMap.remove(globalSession.getXid()) == null) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("GlobalSession To Be Removed Does Not Exists [" + globalSession.getXid() + "]");
|
||||
}
|
||||
}
|
||||
removedGlobalBuffer.add(globalSession.getXid());
|
||||
unhandledBranchBuffer.remove(globalSession.getXid());
|
||||
break;
|
||||
}
|
||||
case BRANCH_ADD:
|
||||
case BRANCH_UPDATE: {
|
||||
BranchSession branchSession = (BranchSession)sessionStorable;
|
||||
if (branchSession.getTransactionId() == 0) {
|
||||
LOGGER.error(
|
||||
"Restore branchSession from file failed, the transactionId is zero , xid:" + branchSession
|
||||
.getXid());
|
||||
break;
|
||||
}
|
||||
if (removedGlobalBuffer.contains(branchSession.getXid())) {
|
||||
break;
|
||||
}
|
||||
GlobalSession foundGlobalSession = sessionMap.get(branchSession.getXid());
|
||||
if (foundGlobalSession == null) {
|
||||
unhandledBranchBuffer.computeIfAbsent(branchSession.getXid(), key -> new HashMap<>())
|
||||
.put(branchSession.getBranchId(), branchSession);
|
||||
} else {
|
||||
BranchSession existingBranch = foundGlobalSession.getBranch(branchSession.getBranchId());
|
||||
if (existingBranch == null) {
|
||||
foundGlobalSession.add(branchSession);
|
||||
} else {
|
||||
existingBranch.setStatus(branchSession.getStatus());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BRANCH_REMOVE: {
|
||||
BranchSession branchSession = (BranchSession)sessionStorable;
|
||||
String xid = branchSession.getXid();
|
||||
if (removedGlobalBuffer.contains(xid)) {
|
||||
break;
|
||||
}
|
||||
long bid = branchSession.getBranchId();
|
||||
if (branchSession.getTransactionId() == 0) {
|
||||
LOGGER.error(
|
||||
"Restore branchSession from file failed, the transactionId is zero , xid:" + branchSession
|
||||
.getXid());
|
||||
break;
|
||||
}
|
||||
GlobalSession found = sessionMap.get(xid);
|
||||
if (found == null) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info(
|
||||
"GlobalSession To Be Updated (Remove Branch) Does Not Exists [" + bid + "/" + xid
|
||||
+ "]");
|
||||
}
|
||||
} else {
|
||||
BranchSession theBranch = found.getBranch(bid);
|
||||
if (theBranch == null) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("BranchSession To Be Updated Does Not Exists [" + bid + "/" + xid + "]");
|
||||
}
|
||||
} else {
|
||||
found.remove(theBranch);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new ShouldNeverHappenException("Unknown Operation: " + logOperation);
|
||||
}
|
||||
}
|
||||
private void restoreSessions(boolean isHistory, Set<String> removedGlobalBuffer,
|
||||
Map<String, Map<Long, BranchSession>> unhandledBranchBuffer) {
|
||||
if (!(transactionStoreManager instanceof ReloadableStore)) {
|
||||
return;
|
||||
}
|
||||
while (((ReloadableStore) transactionStoreManager).hasRemaining(isHistory)) {
|
||||
List<TransactionWriteStore> stores = ((ReloadableStore) transactionStoreManager).readWriteStore(READ_SIZE,
|
||||
isHistory);
|
||||
restore(stores, removedGlobalBuffer, unhandledBranchBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
private void restore(List<TransactionWriteStore> stores, Set<String> removedGlobalBuffer,
|
||||
Map<String, Map<Long, BranchSession>> unhandledBranchBuffer) {
|
||||
for (TransactionWriteStore store : stores) {
|
||||
TransactionStoreManager.LogOperation logOperation = store.getOperate();
|
||||
SessionStorable sessionStorable = store.getSessionRequest();
|
||||
switch (logOperation) {
|
||||
case GLOBAL_ADD:
|
||||
case GLOBAL_UPDATE: {
|
||||
GlobalSession globalSession = (GlobalSession) sessionStorable;
|
||||
if (globalSession.getTransactionId() == 0) {
|
||||
LOGGER.error("Restore globalSession from file failed, the transactionId is zero , xid:"
|
||||
+ globalSession.getXid());
|
||||
break;
|
||||
}
|
||||
if (removedGlobalBuffer.contains(globalSession.getXid())) {
|
||||
break;
|
||||
}
|
||||
GlobalSession foundGlobalSession = sessionMap.get(globalSession.getXid());
|
||||
if (foundGlobalSession == null) {
|
||||
if (this.checkSessionStatus(globalSession)) {
|
||||
sessionMap.put(globalSession.getXid(), globalSession);
|
||||
}
|
||||
else {
|
||||
removedGlobalBuffer.add(globalSession.getXid());
|
||||
unhandledBranchBuffer.remove(globalSession.getXid());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (this.checkSessionStatus(globalSession)) {
|
||||
foundGlobalSession.setStatus(globalSession.getStatus());
|
||||
}
|
||||
else {
|
||||
sessionMap.remove(globalSession.getXid());
|
||||
removedGlobalBuffer.add(globalSession.getXid());
|
||||
unhandledBranchBuffer.remove(globalSession.getXid());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GLOBAL_REMOVE: {
|
||||
GlobalSession globalSession = (GlobalSession) sessionStorable;
|
||||
if (globalSession.getTransactionId() == 0) {
|
||||
LOGGER.error("Restore globalSession from file failed, the transactionId is zero , xid:"
|
||||
+ globalSession.getXid());
|
||||
break;
|
||||
}
|
||||
if (removedGlobalBuffer.contains(globalSession.getXid())) {
|
||||
break;
|
||||
}
|
||||
if (sessionMap.remove(globalSession.getXid()) == null) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("GlobalSession To Be Removed Does Not Exists [" + globalSession.getXid() + "]");
|
||||
}
|
||||
}
|
||||
removedGlobalBuffer.add(globalSession.getXid());
|
||||
unhandledBranchBuffer.remove(globalSession.getXid());
|
||||
break;
|
||||
}
|
||||
case BRANCH_ADD:
|
||||
case BRANCH_UPDATE: {
|
||||
BranchSession branchSession = (BranchSession) sessionStorable;
|
||||
if (branchSession.getTransactionId() == 0) {
|
||||
LOGGER.error("Restore branchSession from file failed, the transactionId is zero , xid:"
|
||||
+ branchSession.getXid());
|
||||
break;
|
||||
}
|
||||
if (removedGlobalBuffer.contains(branchSession.getXid())) {
|
||||
break;
|
||||
}
|
||||
GlobalSession foundGlobalSession = sessionMap.get(branchSession.getXid());
|
||||
if (foundGlobalSession == null) {
|
||||
unhandledBranchBuffer.computeIfAbsent(branchSession.getXid(), key -> new HashMap<>())
|
||||
.put(branchSession.getBranchId(), branchSession);
|
||||
}
|
||||
else {
|
||||
BranchSession existingBranch = foundGlobalSession.getBranch(branchSession.getBranchId());
|
||||
if (existingBranch == null) {
|
||||
foundGlobalSession.add(branchSession);
|
||||
}
|
||||
else {
|
||||
existingBranch.setStatus(branchSession.getStatus());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BRANCH_REMOVE: {
|
||||
BranchSession branchSession = (BranchSession) sessionStorable;
|
||||
String xid = branchSession.getXid();
|
||||
if (removedGlobalBuffer.contains(xid)) {
|
||||
break;
|
||||
}
|
||||
long bid = branchSession.getBranchId();
|
||||
if (branchSession.getTransactionId() == 0) {
|
||||
LOGGER.error("Restore branchSession from file failed, the transactionId is zero , xid:"
|
||||
+ branchSession.getXid());
|
||||
break;
|
||||
}
|
||||
GlobalSession found = sessionMap.get(xid);
|
||||
if (found == null) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("GlobalSession To Be Updated (Remove Branch) Does Not Exists [" + bid + "/"
|
||||
+ xid + "]");
|
||||
}
|
||||
}
|
||||
else {
|
||||
BranchSession theBranch = found.getBranch(bid);
|
||||
if (theBranch == null) {
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("BranchSession To Be Updated Does Not Exists [" + bid + "/" + xid + "]");
|
||||
}
|
||||
}
|
||||
else {
|
||||
found.remove(theBranch);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new ShouldNeverHappenException("Unknown Operation: " + logOperation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
transactionStoreManager.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
transactionStoreManager.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
+598
-565
File diff suppressed because it is too large.
Load diff
+93
-79
@@ -35,91 +35,105 @@ import static io.seata.common.DefaultValues.*;
|
||||
* @author funkye
|
||||
*/
|
||||
public class JedisPooledFactory {
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(JedisPooledFactory.class);
|
||||
|
||||
private static volatile JedisPoolAbstract jedisPool = null;
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(JedisPooledFactory.class);
|
||||
|
||||
private static final String HOST = "127.0.0.1";
|
||||
private static volatile JedisPoolAbstract jedisPool = null;
|
||||
|
||||
private static final int PORT = 6379;
|
||||
private static final int DATABASE = 0;
|
||||
private static final String HOST = "127.0.0.1";
|
||||
|
||||
private static final int SENTINEL_HOST_NUMBER = 3;
|
||||
private static final int PORT = 6379;
|
||||
|
||||
private static final Configuration CONFIGURATION = ConfigurationFactory.getInstance();
|
||||
private static final int DATABASE = 0;
|
||||
|
||||
/**
|
||||
* get the RedisPool instance (singleton)
|
||||
*
|
||||
* @return redisPool
|
||||
*/
|
||||
public static JedisPoolAbstract getJedisPoolInstance(JedisPoolAbstract... jedisPools) {
|
||||
if (jedisPool == null) {
|
||||
synchronized (JedisPooledFactory.class) {
|
||||
if (jedisPool == null) {
|
||||
JedisPoolAbstract tempJedisPool = null;
|
||||
if (jedisPools != null && jedisPools.length > 0) {
|
||||
tempJedisPool = jedisPools[0];
|
||||
} else {
|
||||
String password = CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_PASSWORD);
|
||||
if (StringUtils.isBlank(password)) {
|
||||
password = null;
|
||||
} else {
|
||||
String publicKey = CONFIGURATION.getConfig(ConfigurationKeys.STORE_PUBLIC_KEY);
|
||||
if (StringUtils.isNotBlank(publicKey)) {
|
||||
try {
|
||||
password = ConfigTools.publicDecrypt(password, publicKey);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("decryption failed,please confirm whether the ciphertext and secret key are correct! error msg: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
JedisPoolConfig poolConfig = new JedisPoolConfig();
|
||||
poolConfig.setMinIdle(CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_MIN_CONN,
|
||||
DEFAULT_REDIS_MIN_IDLE));
|
||||
poolConfig.setMaxIdle(CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_MAX_CONN,
|
||||
DEFAULT_REDIS_MAX_IDLE));
|
||||
poolConfig.setMaxTotal(CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_MAX_TOTAL, DEFAULT_REDIS_MAX_TOTAL));
|
||||
String mode = CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_MODE,ConfigurationKeys.REDIS_SINGLE_MODE);
|
||||
if (mode.equals(ConfigurationKeys.REDIS_SENTINEL_MODE)) {
|
||||
String masterName = CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_SENTINEL_MASTERNAME);
|
||||
if (StringUtils.isBlank(masterName)) {
|
||||
throw new RedisException("The masterName is null in redis sentinel mode");
|
||||
}
|
||||
Set<String> sentinels = new HashSet<>(SENTINEL_HOST_NUMBER);
|
||||
String[] sentinelHosts = CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_SENTINEL_HOST).split(",");
|
||||
Arrays.asList(sentinelHosts).forEach(sentinelHost -> sentinels.add(sentinelHost));
|
||||
tempJedisPool = new JedisSentinelPool(masterName, sentinels, poolConfig, 60000, password, CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_DATABASE, DATABASE));
|
||||
} else if (mode.equals(ConfigurationKeys.REDIS_SINGLE_MODE)) {
|
||||
String host = CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_SINGLE_HOST);
|
||||
host = StringUtils.isBlank(host) ? CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_HOST, HOST) : host;
|
||||
int port = CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_SINGLE_PORT);
|
||||
port = port == 0 ? CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_PORT, PORT) : port;
|
||||
tempJedisPool = new JedisPool(poolConfig, host, port, 60000, password, CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_DATABASE, DATABASE));
|
||||
} else {
|
||||
throw new RedisException("Configuration error of redis cluster mode");
|
||||
}
|
||||
}
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("initialization of the build redis connection pool is complete");
|
||||
}
|
||||
jedisPool = tempJedisPool;
|
||||
}
|
||||
}
|
||||
}
|
||||
return jedisPool;
|
||||
}
|
||||
private static final int SENTINEL_HOST_NUMBER = 3;
|
||||
|
||||
/**
|
||||
* get an instance of Jedis (connection) from the connection pool
|
||||
*
|
||||
* @return jedis
|
||||
*/
|
||||
public static Jedis getJedisInstance() {
|
||||
return getJedisPoolInstance().getResource();
|
||||
}
|
||||
private static final Configuration CONFIGURATION = ConfigurationFactory.getInstance();
|
||||
|
||||
/**
|
||||
* get the RedisPool instance (singleton)
|
||||
* @return redisPool
|
||||
*/
|
||||
public static JedisPoolAbstract getJedisPoolInstance(JedisPoolAbstract... jedisPools) {
|
||||
if (jedisPool == null) {
|
||||
synchronized (JedisPooledFactory.class) {
|
||||
if (jedisPool == null) {
|
||||
JedisPoolAbstract tempJedisPool = null;
|
||||
if (jedisPools != null && jedisPools.length > 0) {
|
||||
tempJedisPool = jedisPools[0];
|
||||
}
|
||||
else {
|
||||
String password = CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_PASSWORD);
|
||||
if (StringUtils.isBlank(password)) {
|
||||
password = null;
|
||||
}
|
||||
else {
|
||||
String publicKey = CONFIGURATION.getConfig(ConfigurationKeys.STORE_PUBLIC_KEY);
|
||||
if (StringUtils.isNotBlank(publicKey)) {
|
||||
try {
|
||||
password = ConfigTools.publicDecrypt(password, publicKey);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOGGER.error(
|
||||
"decryption failed,please confirm whether the ciphertext and secret key are correct! error msg: {}",
|
||||
e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
JedisPoolConfig poolConfig = new JedisPoolConfig();
|
||||
poolConfig.setMinIdle(
|
||||
CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_MIN_CONN, DEFAULT_REDIS_MIN_IDLE));
|
||||
poolConfig.setMaxIdle(
|
||||
CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_MAX_CONN, DEFAULT_REDIS_MAX_IDLE));
|
||||
poolConfig.setMaxTotal(
|
||||
CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_MAX_TOTAL, DEFAULT_REDIS_MAX_TOTAL));
|
||||
String mode = CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_MODE,
|
||||
ConfigurationKeys.REDIS_SINGLE_MODE);
|
||||
if (mode.equals(ConfigurationKeys.REDIS_SENTINEL_MODE)) {
|
||||
String masterName = CONFIGURATION
|
||||
.getConfig(ConfigurationKeys.STORE_REDIS_SENTINEL_MASTERNAME);
|
||||
if (StringUtils.isBlank(masterName)) {
|
||||
throw new RedisException("The masterName is null in redis sentinel mode");
|
||||
}
|
||||
Set<String> sentinels = new HashSet<>(SENTINEL_HOST_NUMBER);
|
||||
String[] sentinelHosts = CONFIGURATION
|
||||
.getConfig(ConfigurationKeys.STORE_REDIS_SENTINEL_HOST).split(",");
|
||||
Arrays.asList(sentinelHosts).forEach(sentinelHost -> sentinels.add(sentinelHost));
|
||||
tempJedisPool = new JedisSentinelPool(masterName, sentinels, poolConfig, 60000, password,
|
||||
CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_DATABASE, DATABASE));
|
||||
}
|
||||
else if (mode.equals(ConfigurationKeys.REDIS_SINGLE_MODE)) {
|
||||
String host = CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_SINGLE_HOST);
|
||||
host = StringUtils.isBlank(host)
|
||||
? CONFIGURATION.getConfig(ConfigurationKeys.STORE_REDIS_HOST, HOST) : host;
|
||||
int port = CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_SINGLE_PORT);
|
||||
port = port == 0 ? CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_PORT, PORT) : port;
|
||||
tempJedisPool = new JedisPool(poolConfig, host, port, 60000, password,
|
||||
CONFIGURATION.getInt(ConfigurationKeys.STORE_REDIS_DATABASE, DATABASE));
|
||||
}
|
||||
else {
|
||||
throw new RedisException("Configuration error of redis cluster mode");
|
||||
}
|
||||
}
|
||||
if (LOGGER.isInfoEnabled()) {
|
||||
LOGGER.info("initialization of the build redis connection pool is complete");
|
||||
}
|
||||
jedisPool = tempJedisPool;
|
||||
}
|
||||
}
|
||||
}
|
||||
return jedisPool;
|
||||
}
|
||||
|
||||
/**
|
||||
* get an instance of Jedis (connection) from the connection pool
|
||||
* @return jedis
|
||||
*/
|
||||
public static Jedis getJedisInstance() {
|
||||
return getJedisPoolInstance().getResource();
|
||||
}
|
||||
|
||||
}
|
||||
+52
-47
@@ -28,58 +28,63 @@ import redis.clients.jedis.params.SetParams;
|
||||
|
||||
/**
|
||||
* Redis distributed lock
|
||||
* @author zhongxiang.wang
|
||||
*
|
||||
* @author zhongxiang.wang
|
||||
*/
|
||||
@LoadLevel(name = "redis", scope = Scope.SINGLETON)
|
||||
public class RedisDistributedLocker implements DistributedLocker {
|
||||
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(RedisDistributedLocker.class);
|
||||
private static final String SUCCESS = "OK";
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(RedisDistributedLocker.class);
|
||||
|
||||
/**
|
||||
* Acquire the distributed lock
|
||||
*
|
||||
* @param distributedLockDO the distributed lock info
|
||||
* @return the distributed lock info
|
||||
*/
|
||||
@Override
|
||||
public boolean acquireLock(DistributedLockDO distributedLockDO) {
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
//Don't need retry,if can't acquire the lock,let the other get the lock
|
||||
String result = jedis.set(distributedLockDO.getLockKey(), distributedLockDO.getLockValue(), SetParams.setParams().nx().px(distributedLockDO.getExpireTime()));
|
||||
return SUCCESS.equalsIgnoreCase(result);
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error("The {} acquired the {} distributed lock failed.", distributedLockDO.getLockValue(), distributedLockDO.getLockKey(), ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private static final String SUCCESS = "OK";
|
||||
|
||||
/**
|
||||
* Acquire the distributed lock
|
||||
* @param distributedLockDO the distributed lock info
|
||||
* @return the distributed lock info
|
||||
*/
|
||||
@Override
|
||||
public boolean acquireLock(DistributedLockDO distributedLockDO) {
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
// Don't need retry,if can't acquire the lock,let the other get the lock
|
||||
String result = jedis.set(distributedLockDO.getLockKey(), distributedLockDO.getLockValue(),
|
||||
SetParams.setParams().nx().px(distributedLockDO.getExpireTime()));
|
||||
return SUCCESS.equalsIgnoreCase(result);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
LOGGER.error("The {} acquired the {} distributed lock failed.", distributedLockDO.getLockValue(),
|
||||
distributedLockDO.getLockKey(), ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the distributed lock
|
||||
* @param distributedLockDO the distributed lock info
|
||||
* @return the boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean releaseLock(DistributedLockDO distributedLockDO) {
|
||||
String lockKey = distributedLockDO.getLockKey();
|
||||
String lockValue = distributedLockDO.getLockValue();
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
jedis.watch(lockKey);
|
||||
// Check the value to prevent release the other's lock
|
||||
if (lockValue.equals(jedis.get(lockKey))) {
|
||||
Transaction multi = jedis.multi();
|
||||
multi.del(lockKey);
|
||||
multi.exec();
|
||||
return true;
|
||||
}
|
||||
// The lock hold by others,If other one get the lock,we release lock success
|
||||
// too as for current lockKey
|
||||
jedis.unwatch();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
LOGGER.error("The {} release the {} distributed lock failed.", lockValue, lockKey, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the distributed lock
|
||||
*
|
||||
* @param distributedLockDO the distributed lock info
|
||||
* @return the boolean
|
||||
*/
|
||||
@Override
|
||||
public boolean releaseLock(DistributedLockDO distributedLockDO) {
|
||||
String lockKey = distributedLockDO.getLockKey();
|
||||
String lockValue = distributedLockDO.getLockValue();
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
jedis.watch(lockKey);
|
||||
//Check the value to prevent release the other's lock
|
||||
if (lockValue.equals(jedis.get(lockKey))) {
|
||||
Transaction multi = jedis.multi();
|
||||
multi.del(lockKey);
|
||||
multi.exec();
|
||||
return true;
|
||||
}
|
||||
//The lock hold by others,If other one get the lock,we release lock success too as for current lockKey
|
||||
jedis.unwatch();
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error("The {} release the {} distributed lock failed.", lockValue, lockKey, ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
-30
@@ -29,38 +29,41 @@ import io.seata.server.session.GlobalSession;
|
||||
@LoadLevel(name = "redis")
|
||||
public class RedisLockManager extends AbstractLockManager implements Initialize {
|
||||
|
||||
/**
|
||||
* The locker.
|
||||
*/
|
||||
private Locker locker;
|
||||
/**
|
||||
* The locker.
|
||||
*/
|
||||
private Locker locker;
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
locker = new RedisLocker();
|
||||
}
|
||||
@Override
|
||||
public void init() {
|
||||
locker = new RedisLocker();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locker getLocker(BranchSession branchSession) {
|
||||
return locker;
|
||||
}
|
||||
@Override
|
||||
public Locker getLocker(BranchSession branchSession) {
|
||||
return locker;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(BranchSession branchSession) throws TransactionException {
|
||||
try {
|
||||
return getLocker().releaseLock(branchSession.getXid(), branchSession.getBranchId());
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("unLock error, xid {}, branchId:{}", branchSession.getXid(), branchSession.getBranchId(), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(BranchSession branchSession) throws TransactionException {
|
||||
try {
|
||||
return getLocker().releaseLock(branchSession.getXid(), branchSession.getBranchId());
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("unLock error, xid {}, branchId:{}", branchSession.getXid(), branchSession.getBranchId(), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException {
|
||||
try {
|
||||
return getLocker().releaseLock(globalSession.getXid());
|
||||
}
|
||||
catch (Exception t) {
|
||||
LOGGER.error("unLock globalSession error, xid:{}", globalSession.getXid(), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseGlobalSessionLock(GlobalSession globalSession) throws TransactionException {
|
||||
try {
|
||||
return getLocker().releaseLock(globalSession.getXid());
|
||||
} catch (Exception t) {
|
||||
LOGGER.error("unLock globalSession error, xid:{}", globalSession.getXid(), t);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+310
-297
@@ -40,6 +40,7 @@ import static io.seata.common.Constants.ROW_LOCK_KEY_SPLIT_CHAR;
|
||||
import static io.seata.core.constants.RedisKeyConstants.DEFAULT_REDIS_SEATA_GLOBAL_LOCK_PREFIX;
|
||||
import static io.seata.core.constants.RedisKeyConstants.DEFAULT_REDIS_SEATA_ROW_LOCK_PREFIX;
|
||||
import static io.seata.core.exception.TransactionExceptionCode.LockKeyConflictFailFast;
|
||||
|
||||
/**
|
||||
* The redis lock store operation
|
||||
*
|
||||
@@ -48,338 +49,350 @@ import static io.seata.core.exception.TransactionExceptionCode.LockKeyConflictFa
|
||||
*/
|
||||
public class RedisLocker extends AbstractLocker {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RedisLocker.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RedisLocker.class);
|
||||
|
||||
private static final Integer SUCCEED = 1;
|
||||
private static final Integer SUCCEED = 1;
|
||||
|
||||
private static final Integer FAILED = 0;
|
||||
private static final Integer FAILED = 0;
|
||||
|
||||
private static final String XID = "xid";
|
||||
private static final String XID = "xid";
|
||||
|
||||
private static final String TRANSACTION_ID = "transactionId";
|
||||
private static final String TRANSACTION_ID = "transactionId";
|
||||
|
||||
private static final String BRANCH_ID = "branchId";
|
||||
private static final String BRANCH_ID = "branchId";
|
||||
|
||||
private static final String RESOURCE_ID = "resourceId";
|
||||
private static final String RESOURCE_ID = "resourceId";
|
||||
|
||||
private static final String TABLE_NAME = "tableName";
|
||||
private static final String TABLE_NAME = "tableName";
|
||||
|
||||
private static final String PK = "pk";
|
||||
private static final String PK = "pk";
|
||||
|
||||
private static final String STATUS = "status";
|
||||
private static final String STATUS = "status";
|
||||
|
||||
private static final String ROW_KEY = "rowKey";
|
||||
private static final String ROW_KEY = "rowKey";
|
||||
|
||||
private static final String REDIS_LUA_FILE_NAME = "lua/redislocker/redislock.lua";
|
||||
private static final String REDIS_LUA_FILE_NAME = "lua/redislocker/redislock.lua";
|
||||
|
||||
private static String ACQUIRE_LOCK_SHA;
|
||||
private static String ACQUIRE_LOCK_SHA;
|
||||
|
||||
private static final String WHITE_SPACE = " ";
|
||||
private static final String WHITE_SPACE = " ";
|
||||
|
||||
private static final String ANNOTATION_LUA = "--";
|
||||
private static final String ANNOTATION_LUA = "--";
|
||||
|
||||
/**
|
||||
* Instantiates a new Redis locker.
|
||||
*/
|
||||
public RedisLocker() {
|
||||
if (ACQUIRE_LOCK_SHA == null) {
|
||||
File luaFile = FileLoader.load(REDIS_LUA_FILE_NAME);
|
||||
if (luaFile != null) {
|
||||
StringBuilder acquireLockLuaByFile = new StringBuilder();
|
||||
try (FileInputStream fis = new FileInputStream(luaFile)) {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (line.trim().startsWith(ANNOTATION_LUA)) {
|
||||
continue;
|
||||
}
|
||||
acquireLockLuaByFile.append(line);
|
||||
acquireLockLuaByFile.append(WHITE_SPACE);
|
||||
}
|
||||
// if it fails to read the file, pipeline mode is used
|
||||
} catch (IOException e) {
|
||||
LOGGER.info("redis locker use pipeline mode");
|
||||
return;
|
||||
}
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
ACQUIRE_LOCK_SHA = jedis.scriptLoad(acquireLockLuaByFile.toString());
|
||||
LOGGER.info("redis locker use lua mode");
|
||||
}
|
||||
} else {
|
||||
LOGGER.info("redis locker use pipeline mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Redis locker.
|
||||
*/
|
||||
public RedisLocker() {
|
||||
if (ACQUIRE_LOCK_SHA == null) {
|
||||
File luaFile = FileLoader.load(REDIS_LUA_FILE_NAME);
|
||||
if (luaFile != null) {
|
||||
StringBuilder acquireLockLuaByFile = new StringBuilder();
|
||||
try (FileInputStream fis = new FileInputStream(luaFile)) {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
if (line.trim().startsWith(ANNOTATION_LUA)) {
|
||||
continue;
|
||||
}
|
||||
acquireLockLuaByFile.append(line);
|
||||
acquireLockLuaByFile.append(WHITE_SPACE);
|
||||
}
|
||||
// if it fails to read the file, pipeline mode is used
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOGGER.info("redis locker use pipeline mode");
|
||||
return;
|
||||
}
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
ACQUIRE_LOCK_SHA = jedis.scriptLoad(acquireLockLuaByFile.toString());
|
||||
LOGGER.info("redis locker use lua mode");
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOGGER.info("redis locker use pipeline mode");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> rowLocks) {
|
||||
return acquireLock(rowLocks, true, false);
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> rowLocks) {
|
||||
return acquireLock(rowLocks, true, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> rowLocks, boolean autoCommit, boolean skipCheckLock) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return true;
|
||||
}
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
if (ACQUIRE_LOCK_SHA != null && autoCommit) {
|
||||
return acquireLockByLua(jedis, rowLocks);
|
||||
} else {
|
||||
return acquireLockByPipeline(jedis, rowLocks, autoCommit, skipCheckLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean acquireLock(List<RowLock> rowLocks, boolean autoCommit, boolean skipCheckLock) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return true;
|
||||
}
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
if (ACQUIRE_LOCK_SHA != null && autoCommit) {
|
||||
return acquireLockByLua(jedis, rowLocks);
|
||||
}
|
||||
else {
|
||||
return acquireLockByPipeline(jedis, rowLocks, autoCommit, skipCheckLock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean acquireLockByPipeline(Jedis jedis, List<RowLock> rowLocks, boolean autoCommit, boolean skipCheckLock) {
|
||||
String needLockXid = rowLocks.get(0).getXid();
|
||||
Long branchId = rowLocks.get(0).getBranchId();
|
||||
List<LockDO> needLockDOS = convertToLockDO(rowLocks);
|
||||
if (needLockDOS.size() > 1) {
|
||||
needLockDOS =
|
||||
needLockDOS.stream().filter(LambdaUtils.distinctByKey(LockDO::getRowKey)).collect(Collectors.toList());
|
||||
}
|
||||
List<String> needLockKeys = new ArrayList<>();
|
||||
needLockDOS.forEach(lockDO -> needLockKeys.add(buildLockKey(lockDO.getRowKey())));
|
||||
Map<String, LockDO> needAddLock = new HashMap<>(needLockKeys.size(), 1);
|
||||
private boolean acquireLockByPipeline(Jedis jedis, List<RowLock> rowLocks, boolean autoCommit,
|
||||
boolean skipCheckLock) {
|
||||
String needLockXid = rowLocks.get(0).getXid();
|
||||
Long branchId = rowLocks.get(0).getBranchId();
|
||||
List<LockDO> needLockDOS = convertToLockDO(rowLocks);
|
||||
if (needLockDOS.size() > 1) {
|
||||
needLockDOS = needLockDOS.stream().filter(LambdaUtils.distinctByKey(LockDO::getRowKey))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
List<String> needLockKeys = new ArrayList<>();
|
||||
needLockDOS.forEach(lockDO -> needLockKeys.add(buildLockKey(lockDO.getRowKey())));
|
||||
Map<String, LockDO> needAddLock = new HashMap<>(needLockKeys.size(), 1);
|
||||
|
||||
if (!skipCheckLock) {
|
||||
Pipeline pipeline1 = jedis.pipelined();
|
||||
needLockKeys.stream().forEachOrdered(needLockKey -> {
|
||||
pipeline1.hget(needLockKey, XID);
|
||||
if (!autoCommit) {
|
||||
pipeline1.hget(needLockKey, STATUS);
|
||||
}
|
||||
});
|
||||
List<List<String>> existedLockInfos =
|
||||
Lists.partition((List<String>)(List)pipeline1.syncAndReturnAll(), autoCommit ? 1 : 2);
|
||||
if (!skipCheckLock) {
|
||||
Pipeline pipeline1 = jedis.pipelined();
|
||||
needLockKeys.stream().forEachOrdered(needLockKey -> {
|
||||
pipeline1.hget(needLockKey, XID);
|
||||
if (!autoCommit) {
|
||||
pipeline1.hget(needLockKey, STATUS);
|
||||
}
|
||||
});
|
||||
List<List<String>> existedLockInfos = Lists.partition((List<String>) (List) pipeline1.syncAndReturnAll(),
|
||||
autoCommit ? 1 : 2);
|
||||
|
||||
// When the local transaction and the global transaction are enabled,
|
||||
// the branch registration fails to acquire the global lock,
|
||||
// the lock holder is in the second-stage rollback,
|
||||
// and the branch registration fails to be retried quickly,
|
||||
// because the retry with the local transaction does not release the database lock ,
|
||||
// resulting in a two-phase rollback wait.
|
||||
// Therefore, if a global lock is found in the Rollbacking state,
|
||||
// the fail-fast code is returned directly.
|
||||
if (!autoCommit) {
|
||||
boolean hasRollBackingLock = existedLockInfos.parallelStream().anyMatch(
|
||||
result -> StringUtils.equals(result.get(1), String.valueOf(LockStatus.Rollbacking.getCode())));
|
||||
if (hasRollBackingLock) {
|
||||
throw new StoreException(new BranchTransactionException(LockKeyConflictFailFast));
|
||||
}
|
||||
}
|
||||
// When the local transaction and the global transaction are enabled,
|
||||
// the branch registration fails to acquire the global lock,
|
||||
// the lock holder is in the second-stage rollback,
|
||||
// and the branch registration fails to be retried quickly,
|
||||
// because the retry with the local transaction does not release the database
|
||||
// lock ,
|
||||
// resulting in a two-phase rollback wait.
|
||||
// Therefore, if a global lock is found in the Rollbacking state,
|
||||
// the fail-fast code is returned directly.
|
||||
if (!autoCommit) {
|
||||
boolean hasRollBackingLock = existedLockInfos.parallelStream().anyMatch(
|
||||
result -> StringUtils.equals(result.get(1), String.valueOf(LockStatus.Rollbacking.getCode())));
|
||||
if (hasRollBackingLock) {
|
||||
throw new StoreException(new BranchTransactionException(LockKeyConflictFailFast));
|
||||
}
|
||||
}
|
||||
|
||||
// The logic is executed here, there must be a lock without Rollbacking status when autoCommit equals false
|
||||
for (int i = 0; i < needLockKeys.size(); i++) {
|
||||
List<String> results = existedLockInfos.get(i);
|
||||
String existedLockXid = CollectionUtils.isEmpty(results) ? null : existedLockInfos.get(i).get(0);
|
||||
if (StringUtils.isEmpty(existedLockXid)) {
|
||||
// If empty,we need to lock this row
|
||||
needAddLock.put(needLockKeys.get(i), needLockDOS.get(i));
|
||||
} else {
|
||||
if (!StringUtils.equals(existedLockXid, needLockXid)) {
|
||||
// If not equals,means the rowkey is holding by another global transaction
|
||||
logGlobalLockConflictInfo(needLockXid, needLockKeys.get(i), existedLockXid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needAddLock.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// The logic is executed here, there must be a lock without Rollbacking status
|
||||
// when autoCommit equals false
|
||||
for (int i = 0; i < needLockKeys.size(); i++) {
|
||||
List<String> results = existedLockInfos.get(i);
|
||||
String existedLockXid = CollectionUtils.isEmpty(results) ? null : existedLockInfos.get(i).get(0);
|
||||
if (StringUtils.isEmpty(existedLockXid)) {
|
||||
// If empty,we need to lock this row
|
||||
needAddLock.put(needLockKeys.get(i), needLockDOS.get(i));
|
||||
}
|
||||
else {
|
||||
if (!StringUtils.equals(existedLockXid, needLockXid)) {
|
||||
// If not equals,means the rowkey is holding by another global
|
||||
// transaction
|
||||
logGlobalLockConflictInfo(needLockXid, needLockKeys.get(i), existedLockXid);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needAddLock.isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
List<String> readyKeys = new ArrayList<>(needAddLock.keySet());
|
||||
needAddLock.forEach((key, value) -> {
|
||||
pipeline.hsetnx(key, XID, value.getXid());
|
||||
pipeline.hsetnx(key, TRANSACTION_ID, value.getTransactionId().toString());
|
||||
pipeline.hsetnx(key, BRANCH_ID, value.getBranchId().toString());
|
||||
pipeline.hset(key, ROW_KEY, value.getRowKey());
|
||||
pipeline.hset(key, RESOURCE_ID, value.getResourceId());
|
||||
pipeline.hset(key, TABLE_NAME, value.getTableName());
|
||||
pipeline.hset(key, PK, value.getPk());
|
||||
});
|
||||
List<Integer> results = (List<Integer>) (List) pipeline.syncAndReturnAll();
|
||||
List<List<Integer>> partitions = Lists.partition(results, 7);
|
||||
Pipeline pipeline = jedis.pipelined();
|
||||
List<String> readyKeys = new ArrayList<>(needAddLock.keySet());
|
||||
needAddLock.forEach((key, value) -> {
|
||||
pipeline.hsetnx(key, XID, value.getXid());
|
||||
pipeline.hsetnx(key, TRANSACTION_ID, value.getTransactionId().toString());
|
||||
pipeline.hsetnx(key, BRANCH_ID, value.getBranchId().toString());
|
||||
pipeline.hset(key, ROW_KEY, value.getRowKey());
|
||||
pipeline.hset(key, RESOURCE_ID, value.getResourceId());
|
||||
pipeline.hset(key, TABLE_NAME, value.getTableName());
|
||||
pipeline.hset(key, PK, value.getPk());
|
||||
});
|
||||
List<Integer> results = (List<Integer>) (List) pipeline.syncAndReturnAll();
|
||||
List<List<Integer>> partitions = Lists.partition(results, 7);
|
||||
|
||||
ArrayList<String> success = new ArrayList<>(partitions.size());
|
||||
Integer status = SUCCEED;
|
||||
for (int i = 0; i < partitions.size(); i++) {
|
||||
if (Objects.equals(partitions.get(i).get(0), FAILED)) {
|
||||
status = FAILED;
|
||||
} else {
|
||||
success.add(readyKeys.get(i));
|
||||
}
|
||||
}
|
||||
ArrayList<String> success = new ArrayList<>(partitions.size());
|
||||
Integer status = SUCCEED;
|
||||
for (int i = 0; i < partitions.size(); i++) {
|
||||
if (Objects.equals(partitions.get(i).get(0), FAILED)) {
|
||||
status = FAILED;
|
||||
}
|
||||
else {
|
||||
success.add(readyKeys.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
// If someone has failed,all the lockkey which has been added need to be delete.
|
||||
if (FAILED.equals(status)) {
|
||||
if (success.size() > 0) {
|
||||
jedis.del(success.toArray(new String[0]));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
String xidLockKey = buildXidLockKey(needLockXid);
|
||||
StringJoiner lockKeysString = new StringJoiner(ROW_LOCK_KEY_SPLIT_CHAR);
|
||||
needLockKeys.forEach(lockKeysString::add);
|
||||
jedis.hset(xidLockKey, branchId.toString(), lockKeysString.toString());
|
||||
return true;
|
||||
}
|
||||
// If someone has failed,all the lockkey which has been added need to be delete.
|
||||
if (FAILED.equals(status)) {
|
||||
if (success.size() > 0) {
|
||||
jedis.del(success.toArray(new String[0]));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
String xidLockKey = buildXidLockKey(needLockXid);
|
||||
StringJoiner lockKeysString = new StringJoiner(ROW_LOCK_KEY_SPLIT_CHAR);
|
||||
needLockKeys.forEach(lockKeysString::add);
|
||||
jedis.hset(xidLockKey, branchId.toString(), lockKeysString.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean acquireLockByLua(Jedis jedis, List<RowLock> rowLocks) {
|
||||
String needLockXid = rowLocks.get(0).getXid();
|
||||
Long branchId = rowLocks.get(0).getBranchId();
|
||||
List<LockDO> needLockDOs = rowLocks.stream()
|
||||
.map(this::convertToLockDO)
|
||||
.filter(LambdaUtils.distinctByKey(LockDO::getRowKey))
|
||||
.collect(Collectors.toList());
|
||||
ArrayList<String> keys = new ArrayList<>();
|
||||
ArrayList<String> args = new ArrayList<>();
|
||||
int size = needLockDOs.size();
|
||||
args.add(String.valueOf(size));
|
||||
// args index 2 placeholder
|
||||
args.add(null);
|
||||
args.add(needLockXid);
|
||||
for (LockDO lockDO : needLockDOs) {
|
||||
keys.add(buildLockKey(lockDO.getRowKey()));
|
||||
args.add(lockDO.getTransactionId().toString());
|
||||
args.add(lockDO.getBranchId().toString());
|
||||
args.add(lockDO.getResourceId());
|
||||
args.add(lockDO.getTableName());
|
||||
args.add(lockDO.getRowKey());
|
||||
args.add(lockDO.getPk());
|
||||
}
|
||||
String xidLockKey = buildXidLockKey(needLockXid);
|
||||
StringJoiner lockKeysString = new StringJoiner(ROW_LOCK_KEY_SPLIT_CHAR);
|
||||
needLockDOs.stream().map(lockDO -> buildLockKey(lockDO.getRowKey())).forEach(lockKeysString::add);
|
||||
keys.add(xidLockKey);
|
||||
keys.add(branchId.toString());
|
||||
args.add(lockKeysString.toString());
|
||||
// reset args index 2
|
||||
args.set(1, String.valueOf(args.size()));
|
||||
String xIdOwnLock = (String) jedis.evalsha(ACQUIRE_LOCK_SHA, keys, args);
|
||||
if (xIdOwnLock.equals(needLockXid)) {
|
||||
return true;
|
||||
} else {
|
||||
logGlobalLockConflictInfo(needLockXid, keys.get(0), xIdOwnLock);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private boolean acquireLockByLua(Jedis jedis, List<RowLock> rowLocks) {
|
||||
String needLockXid = rowLocks.get(0).getXid();
|
||||
Long branchId = rowLocks.get(0).getBranchId();
|
||||
List<LockDO> needLockDOs = rowLocks.stream().map(this::convertToLockDO)
|
||||
.filter(LambdaUtils.distinctByKey(LockDO::getRowKey)).collect(Collectors.toList());
|
||||
ArrayList<String> keys = new ArrayList<>();
|
||||
ArrayList<String> args = new ArrayList<>();
|
||||
int size = needLockDOs.size();
|
||||
args.add(String.valueOf(size));
|
||||
// args index 2 placeholder
|
||||
args.add(null);
|
||||
args.add(needLockXid);
|
||||
for (LockDO lockDO : needLockDOs) {
|
||||
keys.add(buildLockKey(lockDO.getRowKey()));
|
||||
args.add(lockDO.getTransactionId().toString());
|
||||
args.add(lockDO.getBranchId().toString());
|
||||
args.add(lockDO.getResourceId());
|
||||
args.add(lockDO.getTableName());
|
||||
args.add(lockDO.getRowKey());
|
||||
args.add(lockDO.getPk());
|
||||
}
|
||||
String xidLockKey = buildXidLockKey(needLockXid);
|
||||
StringJoiner lockKeysString = new StringJoiner(ROW_LOCK_KEY_SPLIT_CHAR);
|
||||
needLockDOs.stream().map(lockDO -> buildLockKey(lockDO.getRowKey())).forEach(lockKeysString::add);
|
||||
keys.add(xidLockKey);
|
||||
keys.add(branchId.toString());
|
||||
args.add(lockKeysString.toString());
|
||||
// reset args index 2
|
||||
args.set(1, String.valueOf(args.size()));
|
||||
String xIdOwnLock = (String) jedis.evalsha(ACQUIRE_LOCK_SHA, keys, args);
|
||||
if (xIdOwnLock.equals(needLockXid)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
logGlobalLockConflictInfo(needLockXid, keys.get(0), xIdOwnLock);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void logGlobalLockConflictInfo(String needLockXid, String lockKey, String xIdOwnLock) {
|
||||
LOGGER.info("tx:[{}] acquire Global lock failed. Global lock on [{}] is holding by xid {}", needLockXid, lockKey, xIdOwnLock);
|
||||
}
|
||||
private void logGlobalLockConflictInfo(String needLockXid, String lockKey, String xIdOwnLock) {
|
||||
LOGGER.info("tx:[{}] acquire Global lock failed. Global lock on [{}] is holding by xid {}", needLockXid,
|
||||
lockKey, xIdOwnLock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return true;
|
||||
}
|
||||
String currentXid = rowLocks.get(0).getXid();
|
||||
Long branchId = rowLocks.get(0).getBranchId();
|
||||
List<LockDO> needReleaseLocks = convertToLockDO(rowLocks);
|
||||
String[] needReleaseKeys = new String[needReleaseLocks.size()];
|
||||
for (int i = 0; i < needReleaseLocks.size(); i++) {
|
||||
needReleaseKeys[i] = buildLockKey(needReleaseLocks.get(i).getRowKey());
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return true;
|
||||
}
|
||||
String currentXid = rowLocks.get(0).getXid();
|
||||
Long branchId = rowLocks.get(0).getBranchId();
|
||||
List<LockDO> needReleaseLocks = convertToLockDO(rowLocks);
|
||||
String[] needReleaseKeys = new String[needReleaseLocks.size()];
|
||||
for (int i = 0; i < needReleaseLocks.size(); i++) {
|
||||
needReleaseKeys[i] = buildLockKey(needReleaseLocks.get(i).getRowKey());
|
||||
}
|
||||
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance(); Pipeline pipelined = jedis.pipelined()) {
|
||||
pipelined.del(needReleaseKeys);
|
||||
pipelined.hdel(buildXidLockKey(currentXid), branchId.toString());
|
||||
pipelined.sync();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance(); Pipeline pipelined = jedis.pipelined()) {
|
||||
pipelined.del(needReleaseKeys);
|
||||
pipelined.hdel(buildXidLockKey(currentXid), branchId.toString());
|
||||
pipelined.sync();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(String xid) {
|
||||
return doReleaseLock(xid, null);
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(String xid) {
|
||||
return doReleaseLock(xid, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseLock(String xid, Long branchId) {
|
||||
if (branchId == null) {
|
||||
return true;
|
||||
}
|
||||
return doReleaseLock(xid, branchId);
|
||||
}
|
||||
@Override
|
||||
public boolean releaseLock(String xid, Long branchId) {
|
||||
if (branchId == null) {
|
||||
return true;
|
||||
}
|
||||
return doReleaseLock(xid, branchId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLockable(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return true;
|
||||
}
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
List<LockDO> locks = convertToLockDO(rowLocks);
|
||||
Set<String> lockKeys = new HashSet<>();
|
||||
for (LockDO rowlock : locks) {
|
||||
lockKeys.add(buildLockKey(rowlock.getRowKey()));
|
||||
}
|
||||
@Override
|
||||
public boolean isLockable(List<RowLock> rowLocks) {
|
||||
if (CollectionUtils.isEmpty(rowLocks)) {
|
||||
return true;
|
||||
}
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
List<LockDO> locks = convertToLockDO(rowLocks);
|
||||
Set<String> lockKeys = new HashSet<>();
|
||||
for (LockDO rowlock : locks) {
|
||||
lockKeys.add(buildLockKey(rowlock.getRowKey()));
|
||||
}
|
||||
|
||||
String xid = rowLocks.get(0).getXid();
|
||||
try (Pipeline pipeline = jedis.pipelined()) {
|
||||
lockKeys.forEach(key -> pipeline.hget(key, XID));
|
||||
List<String> existedXids = (List<String>)(List)pipeline.syncAndReturnAll();
|
||||
return existedXids.stream().allMatch(existedXid -> existedXid == null || xid.equals(existedXid));
|
||||
}
|
||||
}
|
||||
}
|
||||
String xid = rowLocks.get(0).getXid();
|
||||
try (Pipeline pipeline = jedis.pipelined()) {
|
||||
lockKeys.forEach(key -> pipeline.hget(key, XID));
|
||||
List<String> existedXids = (List<String>) (List) pipeline.syncAndReturnAll();
|
||||
return existedXids.stream().allMatch(existedXid -> existedXid == null || xid.equals(existedXid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
String xidLockKey = buildXidLockKey(xid);
|
||||
Map<String, String> branchAndLockKeys = jedis.hgetAll(xidLockKey);
|
||||
if (CollectionUtils.isNotEmpty(branchAndLockKeys)) {
|
||||
try (Pipeline pipeline = jedis.pipelined()) {
|
||||
branchAndLockKeys.values()
|
||||
.forEach(k -> pipeline.hset(k, STATUS, String.valueOf(lockStatus.getCode())));
|
||||
pipeline.sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateLockStatus(String xid, LockStatus lockStatus) {
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
String xidLockKey = buildXidLockKey(xid);
|
||||
Map<String, String> branchAndLockKeys = jedis.hgetAll(xidLockKey);
|
||||
if (CollectionUtils.isNotEmpty(branchAndLockKeys)) {
|
||||
try (Pipeline pipeline = jedis.pipelined()) {
|
||||
branchAndLockKeys.values()
|
||||
.forEach(k -> pipeline.hset(k, STATUS, String.valueOf(lockStatus.getCode())));
|
||||
pipeline.sync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean doReleaseLock(String xid, Long branchId) {
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
String xidLockKey = buildXidLockKey(xid);
|
||||
final List<String> rowKeys = new ArrayList<>();
|
||||
if (null == branchId) {
|
||||
Map<String, String> rowKeyMap = jedis.hgetAll(xidLockKey);
|
||||
rowKeyMap.forEach((branch, rowKey) -> rowKeys.add(rowKey));
|
||||
} else {
|
||||
rowKeys.add(jedis.hget(xidLockKey, branchId.toString()));
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(rowKeys)) {
|
||||
Pipeline pipelined = jedis.pipelined();
|
||||
if (null == branchId) {
|
||||
pipelined.del(xidLockKey);
|
||||
} else {
|
||||
pipelined.hdel(xidLockKey, branchId.toString());
|
||||
}
|
||||
rowKeys.forEach(rowKeyStr -> {
|
||||
if (StringUtils.isNotEmpty(rowKeyStr)) {
|
||||
if (rowKeyStr.contains(ROW_LOCK_KEY_SPLIT_CHAR)) {
|
||||
String[] keys = rowKeyStr.split(ROW_LOCK_KEY_SPLIT_CHAR);
|
||||
pipelined.del(keys);
|
||||
} else {
|
||||
pipelined.del(rowKeyStr);
|
||||
}
|
||||
}
|
||||
});
|
||||
pipelined.sync();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
private boolean doReleaseLock(String xid, Long branchId) {
|
||||
try (Jedis jedis = JedisPooledFactory.getJedisInstance()) {
|
||||
String xidLockKey = buildXidLockKey(xid);
|
||||
final List<String> rowKeys = new ArrayList<>();
|
||||
if (null == branchId) {
|
||||
Map<String, String> rowKeyMap = jedis.hgetAll(xidLockKey);
|
||||
rowKeyMap.forEach((branch, rowKey) -> rowKeys.add(rowKey));
|
||||
}
|
||||
else {
|
||||
rowKeys.add(jedis.hget(xidLockKey, branchId.toString()));
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(rowKeys)) {
|
||||
Pipeline pipelined = jedis.pipelined();
|
||||
if (null == branchId) {
|
||||
pipelined.del(xidLockKey);
|
||||
}
|
||||
else {
|
||||
pipelined.hdel(xidLockKey, branchId.toString());
|
||||
}
|
||||
rowKeys.forEach(rowKeyStr -> {
|
||||
if (StringUtils.isNotEmpty(rowKeyStr)) {
|
||||
if (rowKeyStr.contains(ROW_LOCK_KEY_SPLIT_CHAR)) {
|
||||
String[] keys = rowKeyStr.split(ROW_LOCK_KEY_SPLIT_CHAR);
|
||||
pipelined.del(keys);
|
||||
}
|
||||
else {
|
||||
pipelined.del(rowKeyStr);
|
||||
}
|
||||
}
|
||||
});
|
||||
pipelined.sync();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private String buildXidLockKey(String xid) {
|
||||
return DEFAULT_REDIS_SEATA_GLOBAL_LOCK_PREFIX + xid;
|
||||
}
|
||||
private String buildXidLockKey(String xid) {
|
||||
return DEFAULT_REDIS_SEATA_GLOBAL_LOCK_PREFIX + xid;
|
||||
}
|
||||
|
||||
private String buildLockKey(String rowKey) {
|
||||
return DEFAULT_REDIS_SEATA_ROW_LOCK_PREFIX + rowKey;
|
||||
}
|
||||
private String buildLockKey(String rowKey) {
|
||||
return DEFAULT_REDIS_SEATA_ROW_LOCK_PREFIX + rowKey;
|
||||
}
|
||||
|
||||
}
|
||||
+138
-135
@@ -36,154 +36,157 @@ import java.util.List;
|
||||
* @author funkye
|
||||
*/
|
||||
@LoadLevel(name = "redis", scope = Scope.PROTOTYPE)
|
||||
public class RedisSessionManager extends AbstractSessionManager
|
||||
implements Initialize {
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(RedisSessionManager.class);
|
||||
public class RedisSessionManager extends AbstractSessionManager implements Initialize {
|
||||
|
||||
/**
|
||||
* The Task name.
|
||||
*/
|
||||
protected String taskName;
|
||||
/**
|
||||
* The constant LOGGER.
|
||||
*/
|
||||
protected static final Logger LOGGER = LoggerFactory.getLogger(RedisSessionManager.class);
|
||||
|
||||
/**
|
||||
* Instantiates a new Data base session manager.
|
||||
*/
|
||||
public RedisSessionManager() {
|
||||
super();
|
||||
}
|
||||
/**
|
||||
* The Task name.
|
||||
*/
|
||||
protected String taskName;
|
||||
|
||||
/**
|
||||
* Instantiates a new Data base session manager.
|
||||
*
|
||||
* @param name
|
||||
* the name
|
||||
*/
|
||||
public RedisSessionManager(String name) {
|
||||
super();
|
||||
this.taskName = name;
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Data base session manager.
|
||||
*/
|
||||
public RedisSessionManager() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
transactionStoreManager = RedisTransactionStoreManager.getInstance();
|
||||
}
|
||||
/**
|
||||
* Instantiates a new Data base session manager.
|
||||
* @param name the name
|
||||
*/
|
||||
public RedisSessionManager(String name) {
|
||||
super();
|
||||
this.taskName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (StringUtils.isBlank(taskName)) {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_ADD, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addGlobalSession failed.");
|
||||
}
|
||||
} else {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void init() {
|
||||
transactionStoreManager = RedisTransactionStoreManager.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {
|
||||
if (!StringUtils.isEmpty(taskName)) {
|
||||
return;
|
||||
}
|
||||
session.setStatus(status);
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("updateGlobalSessionStatus failed.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void addGlobalSession(GlobalSession session) throws TransactionException {
|
||||
if (StringUtils.isBlank(taskName)) {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_ADD, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
else {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* remove globalSession 1. rootSessionManager remove normal globalSession 2. retryCommitSessionManager and
|
||||
* retryRollbackSessionManager remove retry expired globalSession
|
||||
*
|
||||
* @param session
|
||||
* the session
|
||||
* @throws TransactionException
|
||||
*/
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_REMOVE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("removeGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateGlobalSessionStatus(GlobalSession session, GlobalStatus status) throws TransactionException {
|
||||
if (!StringUtils.isEmpty(taskName)) {
|
||||
return;
|
||||
}
|
||||
session.setStatus(status);
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("updateGlobalSessionStatus failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
|
||||
if (!StringUtils.isEmpty(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_ADD, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addBranchSession failed.");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* remove globalSession 1. rootSessionManager remove normal globalSession 2.
|
||||
* retryCommitSessionManager and retryRollbackSessionManager remove retry expired
|
||||
* globalSession
|
||||
* @param session the session
|
||||
* @throws TransactionException
|
||||
*/
|
||||
@Override
|
||||
public void removeGlobalSession(GlobalSession session) throws TransactionException {
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.GLOBAL_REMOVE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("removeGlobalSession failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBranchSessionStatus(BranchSession session, BranchStatus status) throws TransactionException {
|
||||
if (!StringUtils.isEmpty(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("updateBranchSessionStatus failed.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void addBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
|
||||
if (!StringUtils.isEmpty(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_ADD, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("addBranchSession failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
|
||||
if (!StringUtils.isEmpty(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_REMOVE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("removeBranchSession failed.");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void updateBranchSessionStatus(BranchSession session, BranchStatus status) throws TransactionException {
|
||||
if (!StringUtils.isEmpty(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_UPDATE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("updateBranchSessionStatus failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid) {
|
||||
return this.findGlobalSession(xid, true);
|
||||
}
|
||||
@Override
|
||||
public void removeBranchSession(GlobalSession globalSession, BranchSession session) throws TransactionException {
|
||||
if (!StringUtils.isEmpty(taskName)) {
|
||||
return;
|
||||
}
|
||||
boolean ret = transactionStoreManager.writeSession(LogOperation.BRANCH_REMOVE, session);
|
||||
if (!ret) {
|
||||
throw new StoreException("removeBranchSession failed.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid, boolean withBranchSessions) {
|
||||
return transactionStoreManager.readSession(xid, withBranchSessions);
|
||||
}
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid) {
|
||||
return this.findGlobalSession(xid, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<GlobalSession> allSessions() {
|
||||
// get by taskName
|
||||
if (SessionHolder.ASYNC_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.AsyncCommitting));
|
||||
} else if (SessionHolder.RETRY_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.CommitRetrying, GlobalStatus.Committing));
|
||||
} else if (SessionHolder.RETRY_ROLLBACKING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.RollbackRetrying, GlobalStatus.Rollbacking,
|
||||
GlobalStatus.TimeoutRollbacking, GlobalStatus.TimeoutRollbackRetrying));
|
||||
} else {
|
||||
// all data
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.UnKnown, GlobalStatus.Begin, GlobalStatus.Committing,
|
||||
GlobalStatus.CommitRetrying, GlobalStatus.Rollbacking, GlobalStatus.RollbackRetrying, GlobalStatus.TimeoutRollbacking,
|
||||
GlobalStatus.TimeoutRollbackRetrying, GlobalStatus.AsyncCommitting));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public GlobalSession findGlobalSession(String xid, boolean withBranchSessions) {
|
||||
return transactionStoreManager.readSession(xid, withBranchSessions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> findGlobalSessions(SessionCondition condition) {
|
||||
// nothing need to do
|
||||
return transactionStoreManager.readSession(condition);
|
||||
}
|
||||
@Override
|
||||
public Collection<GlobalSession> allSessions() {
|
||||
// get by taskName
|
||||
if (SessionHolder.ASYNC_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.AsyncCommitting));
|
||||
}
|
||||
else if (SessionHolder.RETRY_COMMITTING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.CommitRetrying, GlobalStatus.Committing));
|
||||
}
|
||||
else if (SessionHolder.RETRY_ROLLBACKING_SESSION_MANAGER_NAME.equalsIgnoreCase(taskName)) {
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.RollbackRetrying, GlobalStatus.Rollbacking,
|
||||
GlobalStatus.TimeoutRollbacking, GlobalStatus.TimeoutRollbackRetrying));
|
||||
}
|
||||
else {
|
||||
// all data
|
||||
return findGlobalSessions(new SessionCondition(GlobalStatus.UnKnown, GlobalStatus.Begin,
|
||||
GlobalStatus.Committing, GlobalStatus.CommitRetrying, GlobalStatus.Rollbacking,
|
||||
GlobalStatus.RollbackRetrying, GlobalStatus.TimeoutRollbacking,
|
||||
GlobalStatus.TimeoutRollbackRetrying, GlobalStatus.AsyncCommitting));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> findGlobalSessions(SessionCondition condition) {
|
||||
// nothing need to do
|
||||
return transactionStoreManager.readSession(condition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException {
|
||||
return lockCallable.call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T lockAndExecute(GlobalSession globalSession, GlobalSession.LockCallable<T> lockCallable)
|
||||
throws TransactionException {
|
||||
return lockCallable.call();
|
||||
}
|
||||
}
|
||||
+718
-714
File diff suppressed because it is too large.
Load diff
+24
-23
@@ -29,32 +29,33 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class AbstractTransactionStoreManager implements TransactionStoreManager {
|
||||
|
||||
@Override
|
||||
public GlobalSession readSession(String xid) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public GlobalSession readSession(String xid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GlobalSession readSession(String xid, boolean withBranchSessions) {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public GlobalSession readSession(String xid, boolean withBranchSessions) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> readSortByTimeoutBeginSessions(boolean withBranchSessions) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@Override
|
||||
public List<GlobalSession> readSortByTimeoutBeginSessions(boolean withBranchSessions) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> readSession(GlobalStatus[] statuses, boolean withBranchSessions) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@Override
|
||||
public List<GlobalSession> readSession(GlobalStatus[] statuses, boolean withBranchSessions) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GlobalSession> readSession(SessionCondition sessionCondition) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@Override
|
||||
public List<GlobalSession> readSession(SessionCondition sessionCondition) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
}
|
||||
}
|
||||
+24
-22
@@ -23,6 +23,7 @@ import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* The dbcp datasource provider
|
||||
*
|
||||
* @author zhangsen
|
||||
* @author ggndnn
|
||||
* @author will
|
||||
@@ -30,27 +31,28 @@ import javax.sql.DataSource;
|
||||
@LoadLevel(name = "dbcp")
|
||||
public class DbcpDataSourceProvider extends AbstractDataSourceProvider {
|
||||
|
||||
@Override
|
||||
public DataSource generate() {
|
||||
BasicDataSource ds = new BasicDataSource();
|
||||
ds.setDriverClassName(getDriverClassName());
|
||||
// DriverClassLoader works if upgrade commons-dbcp to at least 1.3.1.
|
||||
// https://issues.apache.org/jira/browse/DBCP-333
|
||||
ds.setDriverClassLoader(getDriverClassLoader());
|
||||
ds.setUrl(getUrl());
|
||||
ds.setUsername(getUser());
|
||||
@Override
|
||||
public DataSource generate() {
|
||||
BasicDataSource ds = new BasicDataSource();
|
||||
ds.setDriverClassName(getDriverClassName());
|
||||
// DriverClassLoader works if upgrade commons-dbcp to at least 1.3.1.
|
||||
// https://issues.apache.org/jira/browse/DBCP-333
|
||||
ds.setDriverClassLoader(getDriverClassLoader());
|
||||
ds.setUrl(getUrl());
|
||||
ds.setUsername(getUser());
|
||||
|
||||
ds.setPassword(getPassword());
|
||||
ds.setInitialSize(getMinConn());
|
||||
ds.setMaxTotal(getMaxConn());
|
||||
ds.setMinIdle(getMinConn());
|
||||
ds.setMaxIdle(getMinConn());
|
||||
ds.setMaxWaitMillis(getMaxWait());
|
||||
ds.setTimeBetweenEvictionRunsMillis(120000);
|
||||
ds.setNumTestsPerEvictionRun(1);
|
||||
ds.setTestWhileIdle(true);
|
||||
ds.setValidationQuery(getValidationQuery(getDBType()));
|
||||
ds.setConnectionProperties("useUnicode=yes;characterEncoding=utf8;socketTimeout=5000;connectTimeout=500");
|
||||
return ds;
|
||||
}
|
||||
|
||||
ds.setPassword(getPassword());
|
||||
ds.setInitialSize(getMinConn());
|
||||
ds.setMaxTotal(getMaxConn());
|
||||
ds.setMinIdle(getMinConn());
|
||||
ds.setMaxIdle(getMinConn());
|
||||
ds.setMaxWaitMillis(getMaxWait());
|
||||
ds.setTimeBetweenEvictionRunsMillis(120000);
|
||||
ds.setNumTestsPerEvictionRun(1);
|
||||
ds.setTestWhileIdle(true);
|
||||
ds.setValidationQuery(getValidationQuery(getDBType()));
|
||||
ds.setConnectionProperties("useUnicode=yes;characterEncoding=utf8;socketTimeout=5000;connectTimeout=500");
|
||||
return ds;
|
||||
}
|
||||
}
|
||||
+26
-24
@@ -23,6 +23,7 @@ import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* The druid datasource provider
|
||||
*
|
||||
* @author zhangsen
|
||||
* @author ggndnn
|
||||
* @author will
|
||||
@@ -30,28 +31,29 @@ import javax.sql.DataSource;
|
||||
@LoadLevel(name = "druid")
|
||||
public class DruidDataSourceProvider extends AbstractDataSourceProvider {
|
||||
|
||||
@Override
|
||||
public DataSource generate() {
|
||||
DruidDataSource ds = new DruidDataSource();
|
||||
ds.setDriverClassName(getDriverClassName());
|
||||
ds.setDriverClassLoader(getDriverClassLoader());
|
||||
ds.setUrl(getUrl());
|
||||
ds.setUsername(getUser());
|
||||
ds.setPassword(getPassword());
|
||||
ds.setInitialSize(getMinConn());
|
||||
ds.setMaxActive(getMaxConn());
|
||||
ds.setMinIdle(getMinConn());
|
||||
ds.setMaxWait(getMaxWait());
|
||||
ds.setTimeBetweenEvictionRunsMillis(120000);
|
||||
ds.setMinEvictableIdleTimeMillis(300000);
|
||||
ds.setTestWhileIdle(true);
|
||||
ds.setTestOnBorrow(false);
|
||||
ds.setPoolPreparedStatements(true);
|
||||
ds.setMaxPoolPreparedStatementPerConnectionSize(20);
|
||||
ds.setValidationQuery(getValidationQuery(getDBType()));
|
||||
ds.setDefaultAutoCommit(true);
|
||||
// fix issue 5030
|
||||
ds.setUseOracleImplicitCache(false);
|
||||
return ds;
|
||||
}
|
||||
@Override
|
||||
public DataSource generate() {
|
||||
DruidDataSource ds = new DruidDataSource();
|
||||
ds.setDriverClassName(getDriverClassName());
|
||||
ds.setDriverClassLoader(getDriverClassLoader());
|
||||
ds.setUrl(getUrl());
|
||||
ds.setUsername(getUser());
|
||||
ds.setPassword(getPassword());
|
||||
ds.setInitialSize(getMinConn());
|
||||
ds.setMaxActive(getMaxConn());
|
||||
ds.setMinIdle(getMinConn());
|
||||
ds.setMaxWait(getMaxWait());
|
||||
ds.setTimeBetweenEvictionRunsMillis(120000);
|
||||
ds.setMinEvictableIdleTimeMillis(300000);
|
||||
ds.setTestWhileIdle(true);
|
||||
ds.setTestOnBorrow(false);
|
||||
ds.setPoolPreparedStatements(true);
|
||||
ds.setMaxPoolPreparedStatementPerConnectionSize(20);
|
||||
ds.setValidationQuery(getValidationQuery(getDBType()));
|
||||
ds.setDefaultAutoCommit(true);
|
||||
// fix issue 5030
|
||||
ds.setUseOracleImplicitCache(false);
|
||||
return ds;
|
||||
}
|
||||
|
||||
}
|
||||
+27
-25
@@ -25,36 +25,38 @@ import java.util.Properties;
|
||||
|
||||
/**
|
||||
* The hikari datasource provider
|
||||
*
|
||||
* @author diguage
|
||||
* @author will
|
||||
*/
|
||||
@LoadLevel(name = "hikari")
|
||||
public class HikariDataSourceProvider extends AbstractDataSourceProvider {
|
||||
|
||||
@Override
|
||||
public DataSource generate() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("dataSource.cachePrepStmts", "true");
|
||||
properties.setProperty("dataSource.prepStmtCacheSize", "250");
|
||||
properties.setProperty("dataSource.prepStmtCacheSqlLimit", "2048");
|
||||
properties.setProperty("dataSource.useServerPrepStmts", "true");
|
||||
properties.setProperty("dataSource.useLocalSessionState", "true");
|
||||
properties.setProperty("dataSource.rewriteBatchedStatements", "true");
|
||||
properties.setProperty("dataSource.cacheResultSetMetadata", "true");
|
||||
properties.setProperty("dataSource.cacheServerConfiguration", "true");
|
||||
properties.setProperty("dataSource.elideSetAutoCommits", "true");
|
||||
properties.setProperty("dataSource.maintainTimeStats", "false");
|
||||
@Override
|
||||
public DataSource generate() {
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("dataSource.cachePrepStmts", "true");
|
||||
properties.setProperty("dataSource.prepStmtCacheSize", "250");
|
||||
properties.setProperty("dataSource.prepStmtCacheSqlLimit", "2048");
|
||||
properties.setProperty("dataSource.useServerPrepStmts", "true");
|
||||
properties.setProperty("dataSource.useLocalSessionState", "true");
|
||||
properties.setProperty("dataSource.rewriteBatchedStatements", "true");
|
||||
properties.setProperty("dataSource.cacheResultSetMetadata", "true");
|
||||
properties.setProperty("dataSource.cacheServerConfiguration", "true");
|
||||
properties.setProperty("dataSource.elideSetAutoCommits", "true");
|
||||
properties.setProperty("dataSource.maintainTimeStats", "false");
|
||||
|
||||
HikariConfig config = new HikariConfig(properties);
|
||||
config.setDriverClassName(getDriverClassName());
|
||||
config.setJdbcUrl(getUrl());
|
||||
config.setUsername(getUser());
|
||||
config.setPassword(getPassword());
|
||||
config.setMaximumPoolSize(getMaxConn());
|
||||
config.setMinimumIdle(getMinConn());
|
||||
config.setAutoCommit(true);
|
||||
config.setConnectionTimeout(getMaxWait());
|
||||
config.setInitializationFailTimeout(-1);
|
||||
return new HikariDataSource(config);
|
||||
}
|
||||
|
||||
HikariConfig config = new HikariConfig(properties);
|
||||
config.setDriverClassName(getDriverClassName());
|
||||
config.setJdbcUrl(getUrl());
|
||||
config.setUsername(getUser());
|
||||
config.setPassword(getPassword());
|
||||
config.setMaximumPoolSize(getMaxConn());
|
||||
config.setMinimumIdle(getMinConn());
|
||||
config.setAutoCommit(true);
|
||||
config.setConnectionTimeout(getMaxWait());
|
||||
config.setInitializationFailTimeout(-1);
|
||||
return new HikariDataSource(config);
|
||||
}
|
||||
}
|
||||
+11
-12
@@ -22,17 +22,16 @@ package io.seata.server.store;
|
||||
*/
|
||||
public interface SessionStorable {
|
||||
|
||||
/**
|
||||
* Encode byte [ ].
|
||||
*
|
||||
* @return the byte [ ]
|
||||
*/
|
||||
byte[] encode();
|
||||
/**
|
||||
* Encode byte [ ].
|
||||
* @return the byte [ ]
|
||||
*/
|
||||
byte[] encode();
|
||||
|
||||
/**
|
||||
* Decode.
|
||||
* @param src the src
|
||||
*/
|
||||
void decode(byte[] src);
|
||||
|
||||
/**
|
||||
* Decode.
|
||||
*
|
||||
* @param src the src
|
||||
*/
|
||||
void decode(byte[] src);
|
||||
}
|
||||
+195
-188
@@ -30,219 +30,226 @@ import static io.seata.core.constants.ConfigurationKeys.STORE_FILE_PREFIX;
|
||||
*/
|
||||
public class StoreConfig {
|
||||
|
||||
private static final Configuration CONFIGURATION = ConfigurationFactory.getInstance();
|
||||
private static StoreMode storeMode;
|
||||
private static SessionMode sessionMode;
|
||||
private static LockMode lockMode;
|
||||
private static final Configuration CONFIGURATION = ConfigurationFactory.getInstance();
|
||||
|
||||
/**
|
||||
* set storeMode sessionMode lockMode from StartupParameter
|
||||
*
|
||||
* @param storeMode storeMode
|
||||
* @param sessionMode sessionMode
|
||||
* @param lockMode lockMode
|
||||
*/
|
||||
public static void setStartupParameter(String storeMode, String sessionMode, String lockMode) {
|
||||
if (StringUtils.isNotBlank(storeMode)) {
|
||||
StoreConfig.storeMode = StoreMode.get(storeMode);
|
||||
}
|
||||
if (StringUtils.isNotBlank(sessionMode)) {
|
||||
StoreConfig.sessionMode = SessionMode.get(sessionMode);
|
||||
}
|
||||
if (StringUtils.isNotBlank(lockMode)) {
|
||||
StoreConfig.lockMode = LockMode.get(lockMode);
|
||||
}
|
||||
}
|
||||
private static StoreMode storeMode;
|
||||
|
||||
/**
|
||||
* Default 16kb.
|
||||
*/
|
||||
private static final int DEFAULT_MAX_BRANCH_SESSION_SIZE = 1024 * 16;
|
||||
private static SessionMode sessionMode;
|
||||
|
||||
/**
|
||||
* Default 512b.
|
||||
*/
|
||||
private static final int DEFAULT_MAX_GLOBAL_SESSION_SIZE = 512;
|
||||
private static LockMode lockMode;
|
||||
|
||||
/**
|
||||
* Default 16kb.
|
||||
*/
|
||||
private static final int DEFAULT_WRITE_BUFFER_SIZE = 1024 * 16;
|
||||
/**
|
||||
* set storeMode sessionMode lockMode from StartupParameter
|
||||
* @param storeMode storeMode
|
||||
* @param sessionMode sessionMode
|
||||
* @param lockMode lockMode
|
||||
*/
|
||||
public static void setStartupParameter(String storeMode, String sessionMode, String lockMode) {
|
||||
if (StringUtils.isNotBlank(storeMode)) {
|
||||
StoreConfig.storeMode = StoreMode.get(storeMode);
|
||||
}
|
||||
if (StringUtils.isNotBlank(sessionMode)) {
|
||||
StoreConfig.sessionMode = SessionMode.get(sessionMode);
|
||||
}
|
||||
if (StringUtils.isNotBlank(lockMode)) {
|
||||
StoreConfig.lockMode = LockMode.get(lockMode);
|
||||
}
|
||||
}
|
||||
|
||||
public static int getMaxBranchSessionSize() {
|
||||
return CONFIGURATION.getInt(STORE_FILE_PREFIX + "maxBranchSessionSize", DEFAULT_MAX_BRANCH_SESSION_SIZE);
|
||||
}
|
||||
/**
|
||||
* Default 16kb.
|
||||
*/
|
||||
private static final int DEFAULT_MAX_BRANCH_SESSION_SIZE = 1024 * 16;
|
||||
|
||||
public static int getMaxGlobalSessionSize() {
|
||||
return CONFIGURATION.getInt(STORE_FILE_PREFIX + "maxGlobalSessionSize", DEFAULT_MAX_GLOBAL_SESSION_SIZE);
|
||||
}
|
||||
/**
|
||||
* Default 512b.
|
||||
*/
|
||||
private static final int DEFAULT_MAX_GLOBAL_SESSION_SIZE = 512;
|
||||
|
||||
public static int getFileWriteBufferCacheSize() {
|
||||
return CONFIGURATION.getInt(STORE_FILE_PREFIX + "fileWriteBufferCacheSize", DEFAULT_WRITE_BUFFER_SIZE);
|
||||
}
|
||||
/**
|
||||
* Default 16kb.
|
||||
*/
|
||||
private static final int DEFAULT_WRITE_BUFFER_SIZE = 1024 * 16;
|
||||
|
||||
public static FlushDiskMode getFlushDiskMode() {
|
||||
return FlushDiskMode.findDiskMode(CONFIGURATION.getConfig(STORE_FILE_PREFIX + "flushDiskMode"));
|
||||
}
|
||||
public static int getMaxBranchSessionSize() {
|
||||
return CONFIGURATION.getInt(STORE_FILE_PREFIX + "maxBranchSessionSize", DEFAULT_MAX_BRANCH_SESSION_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* only for inner call
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private static StoreMode getStoreMode() {
|
||||
//startup
|
||||
if (null != storeMode) {
|
||||
return storeMode;
|
||||
}
|
||||
//env
|
||||
String storeModeEnv = ContainerHelper.getStoreMode();
|
||||
if (StringUtils.isNotBlank(storeModeEnv)) {
|
||||
return StoreMode.get(storeModeEnv);
|
||||
}
|
||||
//config
|
||||
String storeModeConfig = CONFIGURATION.getConfig(ConfigurationKeys.STORE_MODE, SERVER_DEFAULT_STORE_MODE);
|
||||
return StoreMode.get(storeModeConfig);
|
||||
}
|
||||
public static int getMaxGlobalSessionSize() {
|
||||
return CONFIGURATION.getInt(STORE_FILE_PREFIX + "maxGlobalSessionSize", DEFAULT_MAX_GLOBAL_SESSION_SIZE);
|
||||
}
|
||||
|
||||
public static SessionMode getSessionMode() {
|
||||
//startup
|
||||
if (null != sessionMode) {
|
||||
return sessionMode;
|
||||
}
|
||||
//env
|
||||
String sessionModeEnv = ContainerHelper.getSessionStoreMode();
|
||||
if (StringUtils.isNotBlank(sessionModeEnv)) {
|
||||
return SessionMode.get(sessionModeEnv);
|
||||
}
|
||||
//config
|
||||
String sessionModeConfig = CONFIGURATION.getConfig(ConfigurationKeys.STORE_SESSION_MODE);
|
||||
if (StringUtils.isNotBlank(sessionModeConfig)) {
|
||||
return SessionMode.get(sessionModeConfig);
|
||||
}
|
||||
// complication old config
|
||||
return SessionMode.get(getStoreMode().name());
|
||||
}
|
||||
public static int getFileWriteBufferCacheSize() {
|
||||
return CONFIGURATION.getInt(STORE_FILE_PREFIX + "fileWriteBufferCacheSize", DEFAULT_WRITE_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
public static LockMode getLockMode() {
|
||||
//startup
|
||||
if (null != lockMode) {
|
||||
return lockMode;
|
||||
}
|
||||
//env
|
||||
String lockModeEnv = ContainerHelper.getLockStoreMode();
|
||||
if (StringUtils.isNotBlank(lockModeEnv)) {
|
||||
return LockMode.get(lockModeEnv);
|
||||
}
|
||||
//config
|
||||
String lockModeConfig = CONFIGURATION.getConfig(ConfigurationKeys.STORE_LOCK_MODE);
|
||||
if (StringUtils.isNotBlank(lockModeConfig)) {
|
||||
return LockMode.get(lockModeConfig);
|
||||
}
|
||||
// complication old config
|
||||
return LockMode.get(getStoreMode().name());
|
||||
}
|
||||
public static FlushDiskMode getFlushDiskMode() {
|
||||
return FlushDiskMode.findDiskMode(CONFIGURATION.getConfig(STORE_FILE_PREFIX + "flushDiskMode"));
|
||||
}
|
||||
|
||||
public enum StoreMode {
|
||||
/**
|
||||
* The File store mode.
|
||||
*/
|
||||
FILE("file"),
|
||||
/**
|
||||
* The Db store mode.
|
||||
*/
|
||||
DB("db"),
|
||||
/**
|
||||
* The Redis store mode.
|
||||
*/
|
||||
REDIS("redis");
|
||||
/**
|
||||
* only for inner call
|
||||
* @return
|
||||
*/
|
||||
private static StoreMode getStoreMode() {
|
||||
// startup
|
||||
if (null != storeMode) {
|
||||
return storeMode;
|
||||
}
|
||||
// env
|
||||
String storeModeEnv = ContainerHelper.getStoreMode();
|
||||
if (StringUtils.isNotBlank(storeModeEnv)) {
|
||||
return StoreMode.get(storeModeEnv);
|
||||
}
|
||||
// config
|
||||
String storeModeConfig = CONFIGURATION.getConfig(ConfigurationKeys.STORE_MODE, SERVER_DEFAULT_STORE_MODE);
|
||||
return StoreMode.get(storeModeConfig);
|
||||
}
|
||||
|
||||
private String name;
|
||||
public static SessionMode getSessionMode() {
|
||||
// startup
|
||||
if (null != sessionMode) {
|
||||
return sessionMode;
|
||||
}
|
||||
// env
|
||||
String sessionModeEnv = ContainerHelper.getSessionStoreMode();
|
||||
if (StringUtils.isNotBlank(sessionModeEnv)) {
|
||||
return SessionMode.get(sessionModeEnv);
|
||||
}
|
||||
// config
|
||||
String sessionModeConfig = CONFIGURATION.getConfig(ConfigurationKeys.STORE_SESSION_MODE);
|
||||
if (StringUtils.isNotBlank(sessionModeConfig)) {
|
||||
return SessionMode.get(sessionModeConfig);
|
||||
}
|
||||
// complication old config
|
||||
return SessionMode.get(getStoreMode().name());
|
||||
}
|
||||
|
||||
StoreMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public static LockMode getLockMode() {
|
||||
// startup
|
||||
if (null != lockMode) {
|
||||
return lockMode;
|
||||
}
|
||||
// env
|
||||
String lockModeEnv = ContainerHelper.getLockStoreMode();
|
||||
if (StringUtils.isNotBlank(lockModeEnv)) {
|
||||
return LockMode.get(lockModeEnv);
|
||||
}
|
||||
// config
|
||||
String lockModeConfig = CONFIGURATION.getConfig(ConfigurationKeys.STORE_LOCK_MODE);
|
||||
if (StringUtils.isNotBlank(lockModeConfig)) {
|
||||
return LockMode.get(lockModeConfig);
|
||||
}
|
||||
// complication old config
|
||||
return LockMode.get(getStoreMode().name());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public enum StoreMode {
|
||||
|
||||
public static StoreMode get(String name) {
|
||||
for (StoreMode mode : StoreMode.values()) {
|
||||
if (mode.getName().equalsIgnoreCase(name)) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("unknown store mode:" + name);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The File store mode.
|
||||
*/
|
||||
FILE("file"),
|
||||
/**
|
||||
* The Db store mode.
|
||||
*/
|
||||
DB("db"),
|
||||
/**
|
||||
* The Redis store mode.
|
||||
*/
|
||||
REDIS("redis");
|
||||
|
||||
public enum SessionMode {
|
||||
/**
|
||||
* The File store mode.
|
||||
*/
|
||||
FILE("file"),
|
||||
/**
|
||||
* The Db store mode.
|
||||
*/
|
||||
DB("db"),
|
||||
/**
|
||||
* The Redis store mode.
|
||||
*/
|
||||
REDIS("redis");
|
||||
private String name;
|
||||
|
||||
private String name;
|
||||
StoreMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
SessionMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public static StoreMode get(String name) {
|
||||
for (StoreMode mode : StoreMode.values()) {
|
||||
if (mode.getName().equalsIgnoreCase(name)) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("unknown store mode:" + name);
|
||||
}
|
||||
|
||||
public static SessionMode get(String name) {
|
||||
for (SessionMode mode : SessionMode.values()) {
|
||||
if (mode.getName().equalsIgnoreCase(name)) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("unknown session mode:" + name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum LockMode {
|
||||
/**
|
||||
* The File store mode.
|
||||
*/
|
||||
FILE("file"),
|
||||
/**
|
||||
* The Db store mode.
|
||||
*/
|
||||
DB("db"),
|
||||
/**
|
||||
* The Redis store mode.
|
||||
*/
|
||||
REDIS("redis");
|
||||
public enum SessionMode {
|
||||
|
||||
private String name;
|
||||
/**
|
||||
* The File store mode.
|
||||
*/
|
||||
FILE("file"),
|
||||
/**
|
||||
* The Db store mode.
|
||||
*/
|
||||
DB("db"),
|
||||
/**
|
||||
* The Redis store mode.
|
||||
*/
|
||||
REDIS("redis");
|
||||
|
||||
LockMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
SessionMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static LockMode get(String name) {
|
||||
for (LockMode mode : LockMode.values()) {
|
||||
if (mode.getName().equalsIgnoreCase(name)) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("unknown lock mode:" + name);
|
||||
}
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static SessionMode get(String name) {
|
||||
for (SessionMode mode : SessionMode.values()) {
|
||||
if (mode.getName().equalsIgnoreCase(name)) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("unknown session mode:" + name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum LockMode {
|
||||
|
||||
/**
|
||||
* The File store mode.
|
||||
*/
|
||||
FILE("file"),
|
||||
/**
|
||||
* The Db store mode.
|
||||
*/
|
||||
DB("db"),
|
||||
/**
|
||||
* The Redis store mode.
|
||||
*/
|
||||
REDIS("redis");
|
||||
|
||||
private String name;
|
||||
|
||||
LockMode(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public static LockMode get(String name) {
|
||||
for (LockMode mode : LockMode.values()) {
|
||||
if (mode.getName().equalsIgnoreCase(name)) {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("unknown lock mode:" + name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+97
-104
@@ -28,121 +28,114 @@ import java.util.List;
|
||||
*/
|
||||
public interface TransactionStoreManager {
|
||||
|
||||
/**
|
||||
* Write session boolean.
|
||||
*
|
||||
* @param logOperation the log operation
|
||||
* @param session the session
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean writeSession(LogOperation logOperation, SessionStorable session);
|
||||
/**
|
||||
* Write session boolean.
|
||||
* @param logOperation the log operation
|
||||
* @param session the session
|
||||
* @return the boolean
|
||||
*/
|
||||
boolean writeSession(LogOperation logOperation, SessionStorable session);
|
||||
|
||||
/**
|
||||
* Read global session global session.
|
||||
* @param xid the xid
|
||||
* @return the global session
|
||||
*/
|
||||
GlobalSession readSession(String xid);
|
||||
|
||||
/**
|
||||
* Read global session global session.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @return the global session
|
||||
*/
|
||||
GlobalSession readSession(String xid);
|
||||
/**
|
||||
* Read session global session.
|
||||
* @param xid the xid
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
GlobalSession readSession(String xid, boolean withBranchSessions);
|
||||
|
||||
/**
|
||||
* Read session global session.
|
||||
*
|
||||
* @param xid the xid
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
GlobalSession readSession(String xid, boolean withBranchSessions);
|
||||
/**
|
||||
* Read session global session by sort by timeout begin status.
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
List<GlobalSession> readSortByTimeoutBeginSessions(boolean withBranchSessions);
|
||||
|
||||
/**
|
||||
* Read session global session by sort by timeout begin status.
|
||||
*
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session
|
||||
*/
|
||||
List<GlobalSession> readSortByTimeoutBeginSessions(boolean withBranchSessions);
|
||||
/**
|
||||
* Read session global session.
|
||||
*
|
||||
* @param statuses the statuses
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session list
|
||||
*/
|
||||
List<GlobalSession> readSession(GlobalStatus[] statuses, boolean withBranchSessions);
|
||||
/**
|
||||
* Read session global session.
|
||||
* @param statuses the statuses
|
||||
* @param withBranchSessions the withBranchSessions
|
||||
* @return the global session list
|
||||
*/
|
||||
List<GlobalSession> readSession(GlobalStatus[] statuses, boolean withBranchSessions);
|
||||
|
||||
/**
|
||||
* Read session by status list.
|
||||
*
|
||||
* @param sessionCondition the session condition
|
||||
* @return the list
|
||||
*/
|
||||
List<GlobalSession> readSession(SessionCondition sessionCondition);
|
||||
/**
|
||||
* Read session by status list.
|
||||
* @param sessionCondition the session condition
|
||||
* @return the list
|
||||
*/
|
||||
List<GlobalSession> readSession(SessionCondition sessionCondition);
|
||||
|
||||
/**
|
||||
* Shutdown.
|
||||
*/
|
||||
void shutdown();
|
||||
/**
|
||||
* Shutdown.
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
/**
|
||||
* The enum Log operation.
|
||||
*/
|
||||
enum LogOperation {
|
||||
|
||||
/**
|
||||
* The enum Log operation.
|
||||
*/
|
||||
enum LogOperation {
|
||||
/**
|
||||
* Global add log operation.
|
||||
*/
|
||||
GLOBAL_ADD((byte) 1),
|
||||
/**
|
||||
* Global update log operation.
|
||||
*/
|
||||
GLOBAL_UPDATE((byte) 2),
|
||||
/**
|
||||
* Global remove log operation.
|
||||
*/
|
||||
GLOBAL_REMOVE((byte) 3),
|
||||
/**
|
||||
* Branch add log operation.
|
||||
*/
|
||||
BRANCH_ADD((byte) 4),
|
||||
/**
|
||||
* Branch update log operation.
|
||||
*/
|
||||
BRANCH_UPDATE((byte) 5),
|
||||
/**
|
||||
* Branch remove log operation.
|
||||
*/
|
||||
BRANCH_REMOVE((byte) 6);
|
||||
|
||||
/**
|
||||
* Global add log operation.
|
||||
*/
|
||||
GLOBAL_ADD((byte)1),
|
||||
/**
|
||||
* Global update log operation.
|
||||
*/
|
||||
GLOBAL_UPDATE((byte)2),
|
||||
/**
|
||||
* Global remove log operation.
|
||||
*/
|
||||
GLOBAL_REMOVE((byte)3),
|
||||
/**
|
||||
* Branch add log operation.
|
||||
*/
|
||||
BRANCH_ADD((byte)4),
|
||||
/**
|
||||
* Branch update log operation.
|
||||
*/
|
||||
BRANCH_UPDATE((byte)5),
|
||||
/**
|
||||
* Branch remove log operation.
|
||||
*/
|
||||
BRANCH_REMOVE((byte)6);
|
||||
private byte code;
|
||||
|
||||
private byte code;
|
||||
LogOperation(byte code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
LogOperation(byte code) {
|
||||
this.code = code;
|
||||
}
|
||||
/**
|
||||
* Gets code.
|
||||
* @return the code
|
||||
*/
|
||||
public byte getCode() {
|
||||
return this.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets code.
|
||||
*
|
||||
* @return the code
|
||||
*/
|
||||
public byte getCode() {
|
||||
return this.code;
|
||||
}
|
||||
/**
|
||||
* Gets log operation by code.
|
||||
* @param code the code
|
||||
* @return the log operation by code
|
||||
*/
|
||||
public static LogOperation getLogOperationByCode(byte code) {
|
||||
for (LogOperation temp : values()) {
|
||||
if (temp.getCode() == code) {
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown LogOperation[" + code + "]");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets log operation by code.
|
||||
*
|
||||
* @param code the code
|
||||
* @return the log operation by code
|
||||
*/
|
||||
public static LogOperation getLogOperationByCode(byte code) {
|
||||
for (LogOperation temp : values()) {
|
||||
if (temp.getCode() == code) {
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown LogOperation[" + code + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
-55
@@ -40,64 +40,66 @@ import static io.seata.core.exception.TransactionExceptionCode.LockKeyConflict;
|
||||
* @author ph3636
|
||||
*/
|
||||
public class ATCore extends AbstractCore {
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
public ATCore(RemotingServer remotingServer) {
|
||||
super(remotingServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchType getHandleBranchType() {
|
||||
return BranchType.AT;
|
||||
}
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Override
|
||||
protected void branchSessionLock(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
String applicationData = branchSession.getApplicationData();
|
||||
boolean autoCommit = true;
|
||||
boolean skipCheckLock = false;
|
||||
if (StringUtils.isNotBlank(applicationData)) {
|
||||
try {
|
||||
Map<String, Object> data = objectMapper.readValue(applicationData, HashMap.class);
|
||||
Object clientAutoCommit = data.get(AUTO_COMMIT);
|
||||
if (clientAutoCommit != null && !(boolean)clientAutoCommit) {
|
||||
autoCommit = (boolean)clientAutoCommit;
|
||||
}
|
||||
Object clientSkipCheckLock = data.get(SKIP_CHECK_LOCK);
|
||||
if (clientSkipCheckLock instanceof Boolean) {
|
||||
skipCheckLock = (boolean)clientSkipCheckLock;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("failed to get application data: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (!branchSession.lock(autoCommit, skipCheckLock)) {
|
||||
throw new BranchTransactionException(LockKeyConflict,
|
||||
String.format("Global lock acquire failed xid = %s branchId = %s", globalSession.getXid(),
|
||||
branchSession.getBranchId()));
|
||||
}
|
||||
} catch (StoreException e) {
|
||||
if (e.getCause() instanceof BranchTransactionException) {
|
||||
throw new BranchTransactionException(((BranchTransactionException)e.getCause()).getCode(),
|
||||
String.format("Global lock acquire failed xid = %s branchId = %s", globalSession.getXid(),
|
||||
branchSession.getBranchId()));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
public ATCore(RemotingServer remotingServer) {
|
||||
super(remotingServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void branchSessionUnlock(BranchSession branchSession) throws TransactionException {
|
||||
branchSession.unlock();
|
||||
}
|
||||
@Override
|
||||
public BranchType getHandleBranchType() {
|
||||
return BranchType.AT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
|
||||
throws TransactionException {
|
||||
return lockManager.isLockable(xid, resourceId, lockKeys);
|
||||
}
|
||||
@Override
|
||||
protected void branchSessionLock(GlobalSession globalSession, BranchSession branchSession)
|
||||
throws TransactionException {
|
||||
String applicationData = branchSession.getApplicationData();
|
||||
boolean autoCommit = true;
|
||||
boolean skipCheckLock = false;
|
||||
if (StringUtils.isNotBlank(applicationData)) {
|
||||
try {
|
||||
Map<String, Object> data = objectMapper.readValue(applicationData, HashMap.class);
|
||||
Object clientAutoCommit = data.get(AUTO_COMMIT);
|
||||
if (clientAutoCommit != null && !(boolean) clientAutoCommit) {
|
||||
autoCommit = (boolean) clientAutoCommit;
|
||||
}
|
||||
Object clientSkipCheckLock = data.get(SKIP_CHECK_LOCK);
|
||||
if (clientSkipCheckLock instanceof Boolean) {
|
||||
skipCheckLock = (boolean) clientSkipCheckLock;
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOGGER.error("failed to get application data: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (!branchSession.lock(autoCommit, skipCheckLock)) {
|
||||
throw new BranchTransactionException(LockKeyConflict,
|
||||
String.format("Global lock acquire failed xid = %s branchId = %s", globalSession.getXid(),
|
||||
branchSession.getBranchId()));
|
||||
}
|
||||
}
|
||||
catch (StoreException e) {
|
||||
if (e.getCause() instanceof BranchTransactionException) {
|
||||
throw new BranchTransactionException(((BranchTransactionException) e.getCause()).getCode(),
|
||||
String.format("Global lock acquire failed xid = %s branchId = %s", globalSession.getXid(),
|
||||
branchSession.getBranchId()));
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void branchSessionUnlock(BranchSession branchSession) throws TransactionException {
|
||||
branchSession.unlock();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean lockQuery(BranchType branchType, String resourceId, String xid, String lockKeys)
|
||||
throws TransactionException {
|
||||
return lockManager.isLockable(xid, resourceId, lockKeys);
|
||||
}
|
||||
|
||||
}
|
||||
+180
-170
@@ -45,186 +45,196 @@ import java.util.concurrent.TimeoutException;
|
||||
*/
|
||||
public class SagaCore extends AbstractCore {
|
||||
|
||||
public SagaCore(RemotingServer remotingServer) {
|
||||
super(remotingServer);
|
||||
}
|
||||
public SagaCore(RemotingServer remotingServer) {
|
||||
super(remotingServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchType getHandleBranchType() {
|
||||
return BranchType.SAGA;
|
||||
}
|
||||
@Override
|
||||
public BranchType getHandleBranchType() {
|
||||
return BranchType.SAGA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void globalSessionStatusCheck(GlobalSession globalSession) throws GlobalTransactionException {
|
||||
// SAGA type accept forward(retry) operation on timeout or commit fail, forward operation will register remaining branches
|
||||
}
|
||||
@Override
|
||||
public void globalSessionStatusCheck(GlobalSession globalSession) throws GlobalTransactionException {
|
||||
// SAGA type accept forward(retry) operation on timeout or commit fail, forward
|
||||
// operation will register remaining branches
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchCommitSend(BranchCommitRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
Map<String, Channel> channels = ChannelManager.getRmChannels();
|
||||
if (CollectionUtils.isEmpty(channels)) {
|
||||
LOGGER.error("Failed to commit SAGA global[" + globalSession.getXid() + ", RM channels is empty.");
|
||||
return BranchStatus.PhaseTwo_CommitFailed_Retryable;
|
||||
}
|
||||
String sagaResourceId = getSagaResourceId(globalSession);
|
||||
Channel sagaChannel = channels.get(sagaResourceId);
|
||||
if (sagaChannel == null) {
|
||||
LOGGER.error("Failed to commit SAGA global[" + globalSession.getXid()
|
||||
+ ", cannot find channel by resourceId[" + sagaResourceId + "]");
|
||||
return BranchStatus.PhaseTwo_CommitFailed_Retryable;
|
||||
}
|
||||
BranchCommitResponse response = (BranchCommitResponse) remotingServer.sendSyncRequest(sagaChannel, request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
@Override
|
||||
public BranchStatus branchCommitSend(BranchCommitRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
Map<String, Channel> channels = ChannelManager.getRmChannels();
|
||||
if (CollectionUtils.isEmpty(channels)) {
|
||||
LOGGER.error("Failed to commit SAGA global[" + globalSession.getXid() + ", RM channels is empty.");
|
||||
return BranchStatus.PhaseTwo_CommitFailed_Retryable;
|
||||
}
|
||||
String sagaResourceId = getSagaResourceId(globalSession);
|
||||
Channel sagaChannel = channels.get(sagaResourceId);
|
||||
if (sagaChannel == null) {
|
||||
LOGGER.error("Failed to commit SAGA global[" + globalSession.getXid()
|
||||
+ ", cannot find channel by resourceId[" + sagaResourceId + "]");
|
||||
return BranchStatus.PhaseTwo_CommitFailed_Retryable;
|
||||
}
|
||||
BranchCommitResponse response = (BranchCommitResponse) remotingServer.sendSyncRequest(sagaChannel, request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchStatus branchRollbackSend(BranchRollbackRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
Map<String, Channel> channels = ChannelManager.getRmChannels();
|
||||
if (CollectionUtils.isEmpty(channels)) {
|
||||
LOGGER.error("Failed to rollback SAGA global[" + globalSession.getXid() + ", RM channels is empty.");
|
||||
return BranchStatus.PhaseTwo_RollbackFailed_Retryable;
|
||||
}
|
||||
String sagaResourceId = getSagaResourceId(globalSession);
|
||||
Channel sagaChannel = channels.get(sagaResourceId);
|
||||
if (sagaChannel == null) {
|
||||
LOGGER.error("Failed to rollback SAGA global[" + globalSession.getXid()
|
||||
+ ", cannot find channel by resourceId[" + sagaResourceId + "]");
|
||||
return BranchStatus.PhaseTwo_RollbackFailed_Retryable;
|
||||
}
|
||||
BranchRollbackResponse response = (BranchRollbackResponse) remotingServer.sendSyncRequest(sagaChannel, request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
@Override
|
||||
public BranchStatus branchRollbackSend(BranchRollbackRequest request, GlobalSession globalSession,
|
||||
BranchSession branchSession) throws IOException, TimeoutException {
|
||||
Map<String, Channel> channels = ChannelManager.getRmChannels();
|
||||
if (CollectionUtils.isEmpty(channels)) {
|
||||
LOGGER.error("Failed to rollback SAGA global[" + globalSession.getXid() + ", RM channels is empty.");
|
||||
return BranchStatus.PhaseTwo_RollbackFailed_Retryable;
|
||||
}
|
||||
String sagaResourceId = getSagaResourceId(globalSession);
|
||||
Channel sagaChannel = channels.get(sagaResourceId);
|
||||
if (sagaChannel == null) {
|
||||
LOGGER.error("Failed to rollback SAGA global[" + globalSession.getXid()
|
||||
+ ", cannot find channel by resourceId[" + sagaResourceId + "]");
|
||||
return BranchStatus.PhaseTwo_RollbackFailed_Retryable;
|
||||
}
|
||||
BranchRollbackResponse response = (BranchRollbackResponse) remotingServer.sendSyncRequest(sagaChannel, request);
|
||||
return response.getBranchStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
try {
|
||||
BranchStatus branchStatus = branchCommit(globalSession, SessionHelper.newBranch(BranchType.SAGA,
|
||||
globalSession.getXid(), -1, getSagaResourceId(globalSession), globalSession.getStatus().name()));
|
||||
@Override
|
||||
public boolean doGlobalCommit(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
try {
|
||||
BranchStatus branchStatus = branchCommit(globalSession, SessionHelper.newBranch(BranchType.SAGA,
|
||||
globalSession.getXid(), -1, getSagaResourceId(globalSession), globalSession.getStatus().name()));
|
||||
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Committed:
|
||||
SessionHelper.removeAllBranch(globalSession, !retrying);
|
||||
LOGGER.info("Successfully committed SAGA global[" + globalSession.getXid() + "]");
|
||||
break;
|
||||
case PhaseTwo_Rollbacked:
|
||||
LOGGER.info("Successfully rollbacked SAGA global[" + globalSession.getXid() + "]");
|
||||
SessionHelper.removeAllBranch(globalSession, !retrying);
|
||||
SessionHelper.endRollbacked(globalSession, retrying);
|
||||
return false;
|
||||
case PhaseTwo_RollbackFailed_Retryable:
|
||||
LOGGER.error("By [{}], failed to rollback SAGA global [{}], will retry later.", branchStatus,
|
||||
globalSession.getXid());
|
||||
SessionHolder.getRetryCommittingSessionManager().removeGlobalSession(globalSession);
|
||||
globalSession.queueToRetryRollback();
|
||||
return false;
|
||||
case PhaseOne_Failed:
|
||||
LOGGER.error("By [{}], finish SAGA global [{}]", branchStatus, globalSession.getXid());
|
||||
SessionHelper.removeAllBranch(globalSession, !retrying);
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Finished);
|
||||
globalSession.end();
|
||||
return false;
|
||||
case PhaseTwo_CommitFailed_Unretryable:
|
||||
if (globalSession.canBeCommittedAsync()) {
|
||||
LOGGER.error("By [{}], failed to commit SAGA global [{}]", branchStatus,
|
||||
globalSession.getXid());
|
||||
break;
|
||||
} else {
|
||||
SessionHelper.endCommitFailed(globalSession,retrying);
|
||||
LOGGER.error("Finally, failed to commit SAGA global[{}]", globalSession.getXid());
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryCommit();
|
||||
} else {
|
||||
LOGGER.error("Failed to commit SAGA global[{}], will retry later.", globalSession.getXid());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error("Failed to commit global[" + globalSession.getXid() + "]", ex);
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Committed:
|
||||
SessionHelper.removeAllBranch(globalSession, !retrying);
|
||||
LOGGER.info("Successfully committed SAGA global[" + globalSession.getXid() + "]");
|
||||
break;
|
||||
case PhaseTwo_Rollbacked:
|
||||
LOGGER.info("Successfully rollbacked SAGA global[" + globalSession.getXid() + "]");
|
||||
SessionHelper.removeAllBranch(globalSession, !retrying);
|
||||
SessionHelper.endRollbacked(globalSession, retrying);
|
||||
return false;
|
||||
case PhaseTwo_RollbackFailed_Retryable:
|
||||
LOGGER.error("By [{}], failed to rollback SAGA global [{}], will retry later.", branchStatus,
|
||||
globalSession.getXid());
|
||||
SessionHolder.getRetryCommittingSessionManager().removeGlobalSession(globalSession);
|
||||
globalSession.queueToRetryRollback();
|
||||
return false;
|
||||
case PhaseOne_Failed:
|
||||
LOGGER.error("By [{}], finish SAGA global [{}]", branchStatus, globalSession.getXid());
|
||||
SessionHelper.removeAllBranch(globalSession, !retrying);
|
||||
globalSession.changeGlobalStatus(GlobalStatus.Finished);
|
||||
globalSession.end();
|
||||
return false;
|
||||
case PhaseTwo_CommitFailed_Unretryable:
|
||||
if (globalSession.canBeCommittedAsync()) {
|
||||
LOGGER.error("By [{}], failed to commit SAGA global [{}]", branchStatus,
|
||||
globalSession.getXid());
|
||||
break;
|
||||
}
|
||||
else {
|
||||
SessionHelper.endCommitFailed(globalSession, retrying);
|
||||
LOGGER.error("Finally, failed to commit SAGA global[{}]", globalSession.getXid());
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryCommit();
|
||||
}
|
||||
else {
|
||||
LOGGER.error("Failed to commit SAGA global[{}], will retry later.", globalSession.getXid());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
LOGGER.error("Failed to commit global[" + globalSession.getXid() + "]", ex);
|
||||
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
try {
|
||||
BranchStatus branchStatus = branchRollback(globalSession, SessionHelper.newBranch(BranchType.SAGA,
|
||||
globalSession.getXid(), -1, getSagaResourceId(globalSession), globalSession.getStatus().name()));
|
||||
@Override
|
||||
public boolean doGlobalRollback(GlobalSession globalSession, boolean retrying) throws TransactionException {
|
||||
try {
|
||||
BranchStatus branchStatus = branchRollback(globalSession, SessionHelper.newBranch(BranchType.SAGA,
|
||||
globalSession.getXid(), -1, getSagaResourceId(globalSession), globalSession.getStatus().name()));
|
||||
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Rollbacked:
|
||||
SessionHelper.removeAllBranch(globalSession, !retrying);
|
||||
LOGGER.info("Successfully rollbacked SAGA global[{}]",globalSession.getXid());
|
||||
break;
|
||||
case PhaseTwo_RollbackFailed_Unretryable:
|
||||
SessionHelper.endRollbackFailed(globalSession, retrying);
|
||||
LOGGER.error("Failed to rollback SAGA global[{}]", globalSession.getXid());
|
||||
return false;
|
||||
case PhaseTwo_CommitFailed_Retryable:
|
||||
SessionHolder.getRetryRollbackingSessionManager().removeGlobalSession(globalSession);
|
||||
globalSession.queueToRetryCommit();
|
||||
LOGGER.warn("Retry by custom recover strategy [Forward] on timeout, SAGA global[{}]", globalSession.getXid());
|
||||
return false;
|
||||
default:
|
||||
LOGGER.error("Failed to rollback SAGA global[{}]", globalSession.getXid());
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error("Failed to rollback global[{}]", globalSession.getXid(), ex);
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
switch (branchStatus) {
|
||||
case PhaseTwo_Rollbacked:
|
||||
SessionHelper.removeAllBranch(globalSession, !retrying);
|
||||
LOGGER.info("Successfully rollbacked SAGA global[{}]", globalSession.getXid());
|
||||
break;
|
||||
case PhaseTwo_RollbackFailed_Unretryable:
|
||||
SessionHelper.endRollbackFailed(globalSession, retrying);
|
||||
LOGGER.error("Failed to rollback SAGA global[{}]", globalSession.getXid());
|
||||
return false;
|
||||
case PhaseTwo_CommitFailed_Retryable:
|
||||
SessionHolder.getRetryRollbackingSessionManager().removeGlobalSession(globalSession);
|
||||
globalSession.queueToRetryCommit();
|
||||
LOGGER.warn("Retry by custom recover strategy [Forward] on timeout, SAGA global[{}]",
|
||||
globalSession.getXid());
|
||||
return false;
|
||||
default:
|
||||
LOGGER.error("Failed to rollback SAGA global[{}]", globalSession.getXid());
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
LOGGER.error("Failed to rollback global[{}]", globalSession.getXid(), ex);
|
||||
if (!retrying) {
|
||||
globalSession.queueToRetryRollback();
|
||||
}
|
||||
throw new TransactionException(ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus globalStatus) throws TransactionException {
|
||||
if (GlobalStatus.Committed.equals(globalStatus)) {
|
||||
SessionHelper.removeAllBranch(globalSession, false);
|
||||
SessionHelper.endCommitted(globalSession,false);
|
||||
LOGGER.info("Global[{}] committed", globalSession.getXid());
|
||||
} else if (GlobalStatus.Rollbacked.equals(globalStatus)
|
||||
|| GlobalStatus.Finished.equals(globalStatus)) {
|
||||
SessionHelper.removeAllBranch(globalSession, false);
|
||||
SessionHelper.endRollbacked(globalSession, false);
|
||||
LOGGER.info("Global[{}] rollbacked", globalSession.getXid());
|
||||
} else {
|
||||
globalSession.changeGlobalStatus(globalStatus);
|
||||
LOGGER.info("Global[{}] reporting is successfully done. status[{}]", globalSession.getXid(), globalSession.getStatus());
|
||||
@Override
|
||||
public void doGlobalReport(GlobalSession globalSession, String xid, GlobalStatus globalStatus)
|
||||
throws TransactionException {
|
||||
if (GlobalStatus.Committed.equals(globalStatus)) {
|
||||
SessionHelper.removeAllBranch(globalSession, false);
|
||||
SessionHelper.endCommitted(globalSession, false);
|
||||
LOGGER.info("Global[{}] committed", globalSession.getXid());
|
||||
}
|
||||
else if (GlobalStatus.Rollbacked.equals(globalStatus) || GlobalStatus.Finished.equals(globalStatus)) {
|
||||
SessionHelper.removeAllBranch(globalSession, false);
|
||||
SessionHelper.endRollbacked(globalSession, false);
|
||||
LOGGER.info("Global[{}] rollbacked", globalSession.getXid());
|
||||
}
|
||||
else {
|
||||
globalSession.changeGlobalStatus(globalStatus);
|
||||
LOGGER.info("Global[{}] reporting is successfully done. status[{}]", globalSession.getXid(),
|
||||
globalSession.getStatus());
|
||||
|
||||
if (GlobalStatus.RollbackRetrying.equals(globalStatus)
|
||||
|| GlobalStatus.TimeoutRollbackRetrying.equals(globalStatus)
|
||||
|| GlobalStatus.UnKnown.equals(globalStatus)) {
|
||||
globalSession.queueToRetryRollback();
|
||||
LOGGER.info("Global[{}] will retry rollback", globalSession.getXid());
|
||||
} else if (GlobalStatus.CommitRetrying.equals(globalStatus)) {
|
||||
globalSession.queueToRetryCommit();
|
||||
LOGGER.info("Global[{}] will retry commit", globalSession.getXid());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (GlobalStatus.RollbackRetrying.equals(globalStatus)
|
||||
|| GlobalStatus.TimeoutRollbackRetrying.equals(globalStatus)
|
||||
|| GlobalStatus.UnKnown.equals(globalStatus)) {
|
||||
globalSession.queueToRetryRollback();
|
||||
LOGGER.info("Global[{}] will retry rollback", globalSession.getXid());
|
||||
}
|
||||
else if (GlobalStatus.CommitRetrying.equals(globalStatus)) {
|
||||
globalSession.queueToRetryCommit();
|
||||
LOGGER.info("Global[{}] will retry commit", globalSession.getXid());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get saga ResourceId
|
||||
* @param globalSession the globalSession
|
||||
* @return sagaResourceId
|
||||
*/
|
||||
private String getSagaResourceId(GlobalSession globalSession) {
|
||||
return globalSession.getApplicationId() + "#" + globalSession.getTransactionServiceGroup();
|
||||
}
|
||||
|
||||
/**
|
||||
* get saga ResourceId
|
||||
*
|
||||
* @param globalSession the globalSession
|
||||
* @return sagaResourceId
|
||||
*/
|
||||
private String getSagaResourceId(GlobalSession globalSession) {
|
||||
return globalSession.getApplicationId() + "#" + globalSession.getTransactionServiceGroup();
|
||||
}
|
||||
}
|
||||
+8
-7
@@ -26,12 +26,13 @@ import io.seata.server.coordinator.AbstractCore;
|
||||
*/
|
||||
public class TccCore extends AbstractCore {
|
||||
|
||||
public TccCore(RemotingServer remotingServer) {
|
||||
super(remotingServer);
|
||||
}
|
||||
public TccCore(RemotingServer remotingServer) {
|
||||
super(remotingServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchType getHandleBranchType() {
|
||||
return BranchType.TCC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchType getHandleBranchType() {
|
||||
return BranchType.TCC;
|
||||
}
|
||||
}
|
||||
+15
-14
@@ -28,21 +28,22 @@ import io.seata.server.coordinator.AbstractCore;
|
||||
*/
|
||||
public class XACore extends AbstractCore {
|
||||
|
||||
public XACore(RemotingServer remotingServer) {
|
||||
super(remotingServer);
|
||||
}
|
||||
public XACore(RemotingServer remotingServer) {
|
||||
super(remotingServer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BranchType getHandleBranchType() {
|
||||
return BranchType.XA;
|
||||
}
|
||||
@Override
|
||||
public BranchType getHandleBranchType() {
|
||||
return BranchType.XA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
|
||||
String applicationData) throws TransactionException {
|
||||
super.branchReport(branchType, xid, branchId, status, applicationData);
|
||||
if (BranchStatus.PhaseOne_Failed == status) {
|
||||
@Override
|
||||
public void branchReport(BranchType branchType, String xid, long branchId, BranchStatus status,
|
||||
String applicationData) throws TransactionException {
|
||||
super.branchReport(branchType, xid, branchId, status, applicationData);
|
||||
if (BranchStatus.PhaseOne_Failed == status) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user