fix(Core/Shared/DB): recommit transactions on dead-lock error (#6069)
This commit is contained in:
@@ -7,6 +7,8 @@
|
|||||||
#include "DatabaseWorkerPool.h"
|
#include "DatabaseWorkerPool.h"
|
||||||
#include "DatabaseEnv.h"
|
#include "DatabaseEnv.h"
|
||||||
|
|
||||||
|
#include <mysqld_error.h>
|
||||||
|
|
||||||
#define MIN_MYSQL_SERVER_VERSION 50700u
|
#define MIN_MYSQL_SERVER_VERSION 50700u
|
||||||
#define MIN_MYSQL_CLIENT_VERSION 50700u
|
#define MIN_MYSQL_CLIENT_VERSION 50700u
|
||||||
|
|
||||||
@@ -318,7 +320,8 @@ template <class T>
|
|||||||
void DatabaseWorkerPool<T>::DirectCommitTransaction(SQLTransaction& transaction)
|
void DatabaseWorkerPool<T>::DirectCommitTransaction(SQLTransaction& transaction)
|
||||||
{
|
{
|
||||||
T* con = GetFreeConnection();
|
T* con = GetFreeConnection();
|
||||||
if (con->ExecuteTransaction(transaction))
|
int errorCode = con->ExecuteTransaction(transaction);
|
||||||
|
if (!errorCode)
|
||||||
{
|
{
|
||||||
con->Unlock(); // OK, operation succesful
|
con->Unlock(); // OK, operation succesful
|
||||||
return;
|
return;
|
||||||
@@ -326,12 +329,12 @@ void DatabaseWorkerPool<T>::DirectCommitTransaction(SQLTransaction& transaction)
|
|||||||
|
|
||||||
//! Handle MySQL Errno 1213 without extending deadlock to the core itself
|
//! Handle MySQL Errno 1213 without extending deadlock to the core itself
|
||||||
//! TODO: More elegant way
|
//! TODO: More elegant way
|
||||||
if (con->GetLastError() == 1213)
|
if (errorCode == ER_LOCK_DEADLOCK)
|
||||||
{
|
{
|
||||||
uint8 loopBreaker = 5;
|
uint8 loopBreaker = 5;
|
||||||
for (uint8 i = 0; i < loopBreaker; ++i)
|
for (uint8 i = 0; i < loopBreaker; ++i)
|
||||||
{
|
{
|
||||||
if (con->ExecuteTransaction(transaction))
|
if (!con->ExecuteTransaction(transaction))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -355,11 +355,11 @@ void MySQLConnection::CommitTransaction()
|
|||||||
Execute("COMMIT");
|
Execute("COMMIT");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
|
int MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
|
||||||
{
|
{
|
||||||
std::list<SQLElementData> const& queries = transaction->m_queries;
|
std::list<SQLElementData> const& queries = transaction->m_queries;
|
||||||
if (queries.empty())
|
if (queries.empty())
|
||||||
return false;
|
return -1;
|
||||||
|
|
||||||
BeginTransaction();
|
BeginTransaction();
|
||||||
|
|
||||||
@@ -376,8 +376,9 @@ bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
|
|||||||
if (!Execute(stmt))
|
if (!Execute(stmt))
|
||||||
{
|
{
|
||||||
LOG_INFO("sql.driver", "[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
LOG_INFO("sql.driver", "[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
||||||
|
int errorCode = GetLastError();
|
||||||
RollbackTransaction();
|
RollbackTransaction();
|
||||||
return false;
|
return errorCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -388,8 +389,9 @@ bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
|
|||||||
if (!Execute(sql))
|
if (!Execute(sql))
|
||||||
{
|
{
|
||||||
LOG_INFO("sql.driver", "[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
LOG_INFO("sql.driver", "[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
||||||
|
int errorCode = GetLastError();
|
||||||
RollbackTransaction();
|
RollbackTransaction();
|
||||||
return false;
|
return errorCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -402,7 +404,7 @@ bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
|
|||||||
// and not while iterating over every element.
|
// and not while iterating over every element.
|
||||||
|
|
||||||
CommitTransaction();
|
CommitTransaction();
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MySQLPreparedStatement* MySQLConnection::GetPreparedStatement(uint32 index)
|
MySQLPreparedStatement* MySQLConnection::GetPreparedStatement(uint32 index)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public:
|
|||||||
void BeginTransaction();
|
void BeginTransaction();
|
||||||
void RollbackTransaction();
|
void RollbackTransaction();
|
||||||
void CommitTransaction();
|
void CommitTransaction();
|
||||||
bool ExecuteTransaction(SQLTransaction& transaction);
|
int ExecuteTransaction(SQLTransaction& transaction);
|
||||||
|
|
||||||
operator bool () const { return m_Mysql != nullptr; }
|
operator bool () const { return m_Mysql != nullptr; }
|
||||||
void Ping() { mysql_ping(m_Mysql); }
|
void Ping() { mysql_ping(m_Mysql); }
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
#include "DatabaseEnv.h"
|
#include "DatabaseEnv.h"
|
||||||
#include "Transaction.h"
|
#include "Transaction.h"
|
||||||
|
|
||||||
|
#include <mysqld_error.h>
|
||||||
|
|
||||||
//- Append a raw ad-hoc query to the transaction
|
//- Append a raw ad-hoc query to the transaction
|
||||||
void Transaction::Append(const char* sql)
|
void Transaction::Append(const char* sql)
|
||||||
{
|
{
|
||||||
@@ -63,14 +65,15 @@ void Transaction::Cleanup()
|
|||||||
|
|
||||||
bool TransactionTask::Execute()
|
bool TransactionTask::Execute()
|
||||||
{
|
{
|
||||||
if (m_conn->ExecuteTransaction(m_trans))
|
int errorCode = m_conn->ExecuteTransaction(m_trans);
|
||||||
|
if (!errorCode)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (m_conn->GetLastError() == 1213)
|
if (errorCode == ER_LOCK_DEADLOCK)
|
||||||
{
|
{
|
||||||
uint8 loopBreaker = 5; // Handle MySQL Errno 1213 without extending deadlock to the core itself
|
uint8 loopBreaker = 5; // Handle MySQL Errno 1213 without extending deadlock to the core itself
|
||||||
for (uint8 i = 0; i < loopBreaker; ++i)
|
for (uint8 i = 0; i < loopBreaker; ++i)
|
||||||
if (m_conn->ExecuteTransaction(m_trans))
|
if (!m_conn->ExecuteTransaction(m_trans))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user