Cherry pick some db commits (#24713)

* Core/DBLayer: Implement async transaction completion callbacks

(cherry picked from commit 0f0ca3a919)

# Conflicts:
#	src/server/bnetserver/REST/LoginRESTService.cpp
#	src/server/bnetserver/Server/Session.cpp
#	src/server/bnetserver/Server/Session.h
#	src/server/database/Database/Transaction.cpp
#	src/server/game/Handlers/CharacterHandler.cpp
#	src/server/game/Handlers/SpellHandler.cpp
#	src/server/game/Server/WorldSession.cpp
#	src/server/game/Server/WorldSocket.cpp
#	src/server/game/Server/WorldSocket.h

* Core/Misc: Fixed char enum packet sometimes not showing newly created character when client latency is too low

(cherry picked from commit fc9d2e728e)

# Conflicts:
#	src/server/game/Handlers/CharacterHandler.cpp

* Fix no-pch build

* Core/Player: Wait for correct transaction on character creation

(cherry picked from commit 01c68b2aa2)

# Conflicts:
#	src/server/game/Entities/Player/Player.cpp

* Fix warning

* Remove unused login transaction

Co-authored-by: Shauren <shauren.trinity@gmail.com>
This commit is contained in:
Giacomo Pozzoni
2020-05-30 15:43:54 +00:00
committed by GitHub
parent 00bc6e7d54
commit 141ada19b0
23 changed files with 281 additions and 160 deletions

View File

@@ -71,7 +71,7 @@ void TransactionBase::Cleanup()
bool TransactionTask::Execute()
{
int errorCode = m_conn->ExecuteTransaction(m_trans);
int errorCode = TryExecute();
if (!errorCode)
return true;
@@ -86,7 +86,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());
@@ -96,7 +96,59 @@ 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;
}