You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
protectedbooleandataValidationAndGoOn(ConnectionProxyconn) throwsSQLException {
// 获取前置镜像内容TableRecordsbeforeRecords = sqlUndoLog.getBeforeImage();
// 获取后置镜像内容TableRecordsafterRecords = sqlUndoLog.getAfterImage();
// Compare current data with before data// No need undo if the before data snapshot is equivalent to the after data snapshot.Result<Boolean> beforeEqualsAfterResult = DataCompareUtils.isRecordsEquals(beforeRecords, afterRecords);
if (beforeEqualsAfterResult.getResult()) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Stop rollback because there is no data change " +
"between the before data snapshot and the after data snapshot.");
}
// no need continue undo.returnfalse;
}
// Validate if data is dirty.// 当前数据TableRecordscurrentRecords = queryCurrentRecords(conn);
// compare with current data and after image.Result<Boolean> afterEqualsCurrentResult = DataCompareUtils.isRecordsEquals(afterRecords, currentRecords);
if (!afterEqualsCurrentResult.getResult()) {
// If current data is not equivalent to the after data, then compare the current data with the before// data, too. No need continue to undo if current data is equivalent to the before data snapshotResult<Boolean> beforeEqualsCurrentResult = DataCompareUtils.isRecordsEquals(beforeRecords, currentRecords);
if (beforeEqualsCurrentResult.getResult()) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Stop rollback because there is no data change " +
"between the before data snapshot and the current data snapshot.");
}
// no need continue undo.returnfalse;
} else {
if (LOGGER.isInfoEnabled()) {
if (StringUtils.isNotBlank(afterEqualsCurrentResult.getErrMsg())) {
LOGGER.info(afterEqualsCurrentResult.getErrMsg(), afterEqualsCurrentResult.getErrMsgParams());
}
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("check dirty data failed, old and new data are not equal, " +
"tableName:[" + sqlUndoLog.getTableName() + "]," +
"oldRows:[" + JSON.toJSONString(afterRecords.getRows()) + "]," +
"newRows:[" + JSON.toJSONString(currentRecords.getRows()) + "].");
}
thrownewSQLUndoDirtyException("Has dirty records when undo.");
}
}
returntrue;
}
上面部分源码中到执行到下面部分源码
TableRecordscurrentRecords = queryCurrentRecords(conn);
// compare with current data and after image.Result<Boolean> afterEqualsCurrentResult = DataCompareUtils.isRecordsEquals(afterRecords, currentRecords);
Ⅰ. Issue Description
使用seata2.0发现事务回滚失败,源码查看是因为seata服务端发起回滚部分代码异常,发现查询分支事务集合由原本的倒序获取改为正序获取,导致客户端回滚因脏数据失败
Ⅱ. Describe what happened
使用seata2.0发现事务回滚失败,源码查看是因为seata服务端发起回滚部分代码异常,发现查询分支事务集合由原本的倒序获取改为正序获取,导致客户端回滚因脏数据失败,测试代码如下
看出我对于order 先进行了save操作,最后有updata操作了一次,2.0回滚失败,1.7正常
我查看源码发现如下问题:
上面部分源码中到执行到下面部分源码
就会被判断为脏数据,因为2.0是正序查询分支事务,那么正序第一次执行的是save操作,那么后置镜像内容与当前数据确实是不一样的因为被update修改了,所以对比就是脏数据了,而1.7倒序就不会有这个问题,修改那次事务的后置镜像与当前数据相同,所以回滚成功。
server端源码部分:
我不确定这是bug还是对2.0增加了其他什么操作需要正序查询分支事务
Ⅵ. Environment:
The text was updated successfully, but these errors were encountered: