Core/DBLayer: Implement async transaction completion callbacks

This commit is contained in:
Shauren authored and Ovahlord committed 2020-04-15 21:41:14 +02:00
1 parent 882c275e65
commit ca881f7e3f
22 files changed
+246 -141

No files matched your search

+56 -3
View File
@@ -70,7 +70,7 @@ void TransactionBase::Cleanup()
bool TransactionTask::Execute()
{
int errorCode = m_conn->ExecuteTransaction(m_trans);
int errorCode = TryExecute();
if (!errorCode)
return true;
@@ -85,7 +85,7 @@ bool TransactionTask::Execute()
for (uint32 loopDuration = 0, startMSTime = getMSTime(); loopDuration <= DEADLOCK_MAX_RETRY_TIME_MS; loopDuration = GetMSTimeDiffToNow(startMSTime))
{
if (!m_conn->ExecuteTransaction(m_trans))
if (!TryExecute())
return true;
TC_LOG_WARN("sql.sql", "Deadlocked SQL Transaction, retrying. Loop timer: %u ms, Thread Id: %s", loopDuration, threadId.c_str());
@@ -95,7 +95,60 @@ bool TransactionTask::Execute()
}
// Clean up now.
m_trans->Cleanup();
CleanupOnFailure();
return false;
}
int TransactionTask::TryExecute()
{
return m_conn->ExecuteTransaction(m_trans);
}
void TransactionTask::CleanupOnFailure()
{
m_trans->Cleanup();
}
bool TransactionWithResultTask::Execute()
{
int errorCode = TryExecute();
if (!errorCode)
{
m_result.set_value(true);
return true;
}
if (errorCode == ER_LOCK_DEADLOCK)
{
// Make sure only 1 async thread retries a transaction so they don't keep dead-locking each other
std::lock_guard<std::mutex> lock(_deadlockLock);
uint8 loopBreaker = 5; // Handle MySQL Errno 1213 without extending deadlock to the core itself
for (uint8 i = 0; i < loopBreaker; ++i)
{
if (!TryExecute())
{
m_result.set_value(true);
return true;
}
}
}
// Clean up now.
CleanupOnFailure();
m_result.set_value(false);
return false;
}
bool TransactionCallback::InvokeIfReady()
{
if (m_future.valid() && m_future.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
m_callback(m_future.get());
return true;
}
return false;
}