Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix: fix tablemeta refresh after closed #7044

Merged
merged 8 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/en-us/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Add changes here for all PR submitted to the 2.x branch.
- [[#7010](https://github.com/apache/incubator-seata/pull/7010)] fix error while the "context" is key word in DM8 when delete undolog
- [[#7022](https://github.com/apache/incubator-seata/pull/7022)] fix `store.mode` property in `application.raft.example.yml`
- [[#7025](https://github.com/apache/incubator-seata/pull/7025)] fix vGroupMappingManager is NOT init
- [[#7044](https://github.com/apache/incubator-seata/pull/7044)] fix tableMeta refresh after closed
-
### optimize:
- [[#6826](https://github.com/apache/incubator-seata/pull/6826)] remove the branch registration operation of the XA read-only transaction
Expand Down
1 change: 1 addition & 0 deletions changes/zh-cn/2.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
- [[#7010](https://github.com/apache/incubator-seata/pull/7010)] 修复使用达梦数据库时删除undolog发生SQL语法错误
- [[#7022](https://github.com/apache/incubator-seata/pull/7022)] 修复 `application.raft.example.yml`的 `store.mode`属性
- [[#7025](https://github.com/apache/incubator-seata/pull/7025)] 修复vGroupMappingManager未初始化的问题
- [[#7044](https://github.com/apache/incubator-seata/pull/7044)] 修复TableMeta在数据源关闭后刷新错误问题

### optimize:
- [[#6826](https://github.com/apache/incubator-seata/pull/6826)] 移除只读XA事务的分支注册操作
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.seata.rm.datasource.sql.struct;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -29,6 +30,7 @@
import org.apache.seata.common.loader.EnhancedServiceLoader;
import org.apache.seata.common.thread.NamedThreadFactory;
import org.apache.seata.common.util.CollectionUtils;
import org.apache.seata.common.util.StringUtils;
import org.apache.seata.config.ConfigurationFactory;
import org.apache.seata.rm.datasource.DataSourceProxy;
import org.apache.seata.sqlparser.struct.TableMetaCache;
Expand Down Expand Up @@ -99,6 +101,14 @@ public static void tableMetaRefreshEvent(String resourceId) {
}
}

/**
* Remove the TableMetaRefreshHolder from the map.
*/
private static void removeHolderFromMap(String resourceId) {
TABLE_META_REFRESH_HOLDER_MAP.remove(resourceId);
LOGGER.info("Removed TableMetaRefreshHolder for resourceId: {}", resourceId);
}

static class TableMetaRefreshHolder {
private long lastRefreshFinishTime;
private DataSourceProxy dataSource;
Expand Down Expand Up @@ -133,6 +143,16 @@ static class TableMetaRefreshHolder {
}
lastRefreshFinishTime = System.nanoTime();
}
} catch (SQLException ex) {
if (isDataSourceClosedException(ex)) {
LOGGER.info("DataSource is closed, exiting refresh task for resourceId: {}", dataSource.getResourceId());
removeHolderFromMap(dataSource.getResourceId());
return;
} else {
// other error, avoid high CPU usage due to infinite loops caused by database exceptions
LOGGER.error("Table refresh SQL error: {}", ex.getMessage(), ex);
lastRefreshFinishTime = System.nanoTime();
}
} catch (Exception exx) {
LOGGER.error("table refresh error:{}", exx.getMessage(), exx);
// Avoid high CPU usage due to infinite loops caused by database exceptions
Expand All @@ -142,7 +162,20 @@ static class TableMetaRefreshHolder {
});
}



/**
* Helper method to determine if the exception is caused by the data source being closed.
*
* @param ex the SQLException to check
* @return true if the exception indicates the data source is closed; false otherwise
*/
private boolean isDataSourceClosedException(SQLException ex) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's just the connection being closed, can the two be distinguished?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use sqlState 08006 and exception message keywords to distinguish

String message = ex.getMessage().toLowerCase();
String sqlState = ex.getSQLState();
// Most jdbc drivers use '08006' as the datasource close code.
if ("08006".equals(sqlState)) {
return true;
}
return StringUtils.isNotBlank(message) && message.contains("datasource") && message.contains("close");
}
}
}
Loading