Shared/Database: Fix transactions not being recommitted on dead-lock error

Fix transactions not being recommitted on dead-lock error (error code 1213) because of calling http://dev.mysql.com/doc/refman/5.0/en/mysql-errno.html after sending the ROLLBACK command. This way the returned error code was related to the ROLLBACK command, not the failed transaction.

(cherry picked from commit d4db0c15c7)
This commit is contained in:
jackpoz
2015-02-03 22:16:41 +01:00
committed by Nayd
parent d2b7268f1d
commit 7c3a2e163a
4 changed files with 17 additions and 12 deletions

View File

@@ -368,7 +368,8 @@ class DatabaseWorkerPool
void DirectCommitTransaction(SQLTransaction& transaction)
{
T* con = GetFreeConnection();
if (con->ExecuteTransaction(transaction))
int errorCode = con->ExecuteTransaction(transaction);
if (!errorCode)
{
con->Unlock(); // OK, operation succesful
return;
@@ -376,12 +377,12 @@ class DatabaseWorkerPool
//! Handle MySQL Errno 1213 without extending deadlock to the core itself
/// @todo More elegant way
if (con->GetLastError() == 1213)
if (errorCode == ER_LOCK_DEADLOCK)
{
uint8 loopBreaker = 5;
for (uint8 i = 0; i < loopBreaker; ++i)
{
if (con->ExecuteTransaction(transaction))
if (!con->ExecuteTransaction(transaction))
break;
}
}

View File

@@ -359,11 +359,11 @@ void MySQLConnection::CommitTransaction()
Execute("COMMIT");
}
bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
int MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
{
std::list<SQLElementData> const& queries = transaction->m_queries;
if (queries.empty())
return false;
return -1;
BeginTransaction();
@@ -380,8 +380,9 @@ bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
if (!Execute(stmt))
{
TC_LOG_WARN("sql.sql", "Transaction aborted. %u queries not executed.", (uint32)queries.size());
int errorCode = GetLastError();
RollbackTransaction();
return false;
return errorCode;
}
}
break;
@@ -392,8 +393,9 @@ bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
if (!Execute(sql))
{
TC_LOG_WARN("sql.sql", "Transaction aborted. %u queries not executed.", (uint32)queries.size());
int errorCode = GetLastError();
RollbackTransaction();
return false;
return errorCode;
}
}
break;
@@ -406,7 +408,7 @@ bool MySQLConnection::ExecuteTransaction(SQLTransaction& transaction)
// and not while iterating over every element.
CommitTransaction();
return true;
return 0;
}
MySQLPreparedStatement* MySQLConnection::GetPreparedStatement(uint32 index)

View File

@@ -86,7 +86,7 @@ class MySQLConnection
void BeginTransaction();
void RollbackTransaction();
void CommitTransaction();
bool ExecuteTransaction(SQLTransaction& transaction);
int ExecuteTransaction(SQLTransaction& transaction);
operator bool () const { return m_Mysql != NULL; }
void Ping() { mysql_ping(m_Mysql); }

View File

@@ -17,6 +17,7 @@
#include "DatabaseEnv.h"
#include "Transaction.h"
#include <mysqld_error.h>
//- Append a raw ad-hoc query to the transaction
void Transaction::Append(const char* sql)
@@ -74,14 +75,15 @@ void Transaction::Cleanup()
bool TransactionTask::Execute()
{
if (m_conn->ExecuteTransaction(m_trans))
int errorCode = m_conn->ExecuteTransaction(m_trans);
if (!errorCode)
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
for (uint8 i = 0; i < loopBreaker; ++i)
if (m_conn->ExecuteTransaction(m_trans))
if (!m_conn->ExecuteTransaction(m_trans))
return true;
}