Skip to content

Commit

Permalink
优化 MySQL Statement 准备失败时尝试重连
Browse files Browse the repository at this point in the history
  • Loading branch information
fasiondog committed Nov 23, 2024
1 parent 7c73f91 commit 03de4eb
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 20 deletions.
45 changes: 26 additions & 19 deletions hikyuu/utilities/db_connect/mysql/MySQLStatement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,7 @@ MySQLStatement::MySQLStatement(DBConnectBase* driver, const std::string& sql_sta
m_meta_result(nullptr),
m_needs_reset(false),
m_has_bind_result(false) {
if (!_prepare()) {
// 尝试重连
if ((dynamic_cast<MySQLConnect*>(driver))->ping()) {
m_db = (dynamic_cast<MySQLConnect*>(driver))->m_mysql;
HKU_CHECK(_prepare(), "Failed prepare statement, while reconnect to mysql!");
HKU_INFO("success reconnect to mysql");
} else {
HKU_THROW("Failed reconnect mysql!");
}
}
_prepare(driver);

auto param_count = mysql_stmt_param_count(m_stmt);
if (param_count > 0) {
Expand All @@ -65,19 +56,35 @@ MySQLStatement::~MySQLStatement() {
mysql_stmt_close(m_stmt);
}

bool MySQLStatement::_prepare() {
void MySQLStatement::_prepare(DBConnectBase* driver) {
m_stmt = mysql_stmt_init(m_db);
HKU_ERROR_IF_RETURN(!m_stmt, false, "Failed mysql_stmt_init!");
HKU_CHECK(m_stmt, "Failed mysql_stmt_init!");

int ret = mysql_stmt_prepare(m_stmt, m_sql_string.c_str(), m_sql_string.size());
if (ret != 0) {
std::string stmt_errorstr(mysql_stmt_error(m_stmt));
mysql_stmt_close(m_stmt);
m_stmt = nullptr;
HKU_ERROR("Failed prepare sql statement: {}! error msg: {}!", m_sql_string, stmt_errorstr);
return false;
HKU_IF_RETURN(0 == ret, void());

mysql_stmt_close(m_stmt);
m_stmt = nullptr;

// 如果是服务器异常,尝试重连服务器
if (CR_SERVER_LOST == ret || CR_SERVER_GONE_ERROR == ret) {
if ((dynamic_cast<MySQLConnect*>(driver))->ping()) {
m_db = (dynamic_cast<MySQLConnect*>(driver))->m_mysql;
} else {
HKU_THROW("Failed reconnect mysql!");
}
} else if (CR_OUT_OF_MEMORY == ret) {
HKU_THROW("Out of memory!");
}
return true;

m_stmt = mysql_stmt_init(m_db);
ret = mysql_stmt_prepare(m_stmt, m_sql_string.c_str(), m_sql_string.size());
HKU_IF_RETURN(0 == ret, void());

std::string stmt_errorstr(mysql_stmt_error(m_stmt));
mysql_stmt_close(m_stmt);
m_stmt = nullptr;
HKU_THROW("Failed prepare statement: {}! error msg: {}!", m_sql_string, stmt_errorstr);
}

void MySQLStatement::_reset() {
Expand Down
2 changes: 1 addition & 1 deletion hikyuu/utilities/db_connect/mysql/MySQLStatement.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class HKU_UTILS_API MySQLStatement : public SQLStatementBase {
virtual void sub_getColumnAsBlob(int idx, std::vector<char> &item) override;

private:
bool _prepare();
void _prepare(DBConnectBase *driver);
void _reset();
void _bindResult();

Expand Down
4 changes: 4 additions & 0 deletions release.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# 版本发布说明

## 1.1.1 -

优化 MySQL Statement 准备失败时尝试重连

## 1.1.0 - 2024年11月12日

1. fixed DBUpgrade 判断 sqlite 还是 mysql 示例
Expand Down

0 comments on commit 03de4eb

Please sign in to comment.