8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 06:43:04 +01:00

Fixed bug CORE-2183 : Error in ExtDS when server shutdown started with opened Execute Statement

This commit is contained in:
hvlad 2008-11-17 12:30:28 +00:00
parent 7ce8528fc2
commit 62ca23fa58
7 changed files with 78 additions and 23 deletions

View File

@ -369,6 +369,18 @@ void Connection::releaseStatement(Jrd::thread_db *tdbb, Statement *stmt)
m_provider.releaseConnection(JRD_get_thread_data(), *this);
}
void Connection::clearTransactions(Jrd::thread_db *tdbb)
{
Transaction **tran_ptr = m_transactions.begin();
Transaction **end = m_transactions.end();
while (m_transactions.getCount())
{
Transaction *tran = m_transactions[0];
tran->rollback(tdbb, false);
}
}
void Connection::clearStatements(thread_db *tdbb)
{
Statement **stmt_ptr = m_statements.begin();
@ -389,6 +401,19 @@ void Connection::clearStatements(thread_db *tdbb)
m_free_stmts = m_used_stmts = 0;
}
void Connection::detach(thread_db *tdbb)
{
const bool was_deleting = m_deleting;
m_deleting = true;
clearStatements(tdbb);
clearTransactions(tdbb);
m_deleting = was_deleting;
doDetach(tdbb);
}
Transaction* Connection::findTransaction(thread_db *tdbb, TraScope traScope) const
{
jrd_tra *tran = tdbb->getTransaction();
@ -494,11 +519,13 @@ void Transaction::start(thread_db *tdbb, TraScope traScope, TraModes traMode,
{
case traCommon :
this->m_nextTran = tran->tra_ext_common;
this->m_jrdTran = tran;
tran->tra_ext_common = this;
break;
case traTwoPhase :
// join transaction
// this->m_jrdTran = tran;
// tran->tra_ext_two_phase = ext_tran;
break;
}
@ -523,7 +550,9 @@ void Transaction::commit(thread_db *tdbb, bool retain)
m_connection.raise(status, tdbb, "transaction commit");
}
if (!retain) {
if (!retain)
{
detachFromJrdTran();
m_connection.deleteTransaction(this);
}
}
@ -533,7 +562,9 @@ void Transaction::rollback(thread_db *tdbb, bool retain)
ISC_STATUS_ARRAY status = {0};
doRollback(status, tdbb, retain);
if (!retain) {
if (!retain)
{
detachFromJrdTran();
m_connection.deleteTransaction(this);
}
@ -581,15 +612,35 @@ Transaction* Transaction::getTransaction(thread_db *tdbb, Connection *conn, TraS
return ext_tran;
}
void Transaction::detachFromJrdTran()
{
if (m_scope != traCommon)
return;
fb_assert(m_jrdTran);
if (!m_jrdTran)
return;
Transaction **tran_ptr = &m_jrdTran->tra_ext_common;
for (; *tran_ptr; tran_ptr = &(*tran_ptr)->m_nextTran)
{
if (*tran_ptr == this)
{
*tran_ptr = this->m_nextTran;
this->m_nextTran = NULL;
return;
}
}
fb_assert(false);
}
void Transaction::jrdTransactionEnd(thread_db *tdbb, jrd_tra* transaction,
bool commit, bool retain, bool force)
{
Transaction** ext_tran = &transaction->tra_ext_common;
Transaction* tran = *ext_tran;
while (tran)
while (transaction->tra_ext_common)
{
Transaction* next = tran->m_nextTran;
Transaction* tran = transaction->tra_ext_common;
try
{
if (commit)
@ -604,11 +655,7 @@ void Transaction::jrdTransactionEnd(thread_db *tdbb, jrd_tra* transaction,
// ignore rollback error
fb_utils::init_status(tdbb->tdbb_status_vector);
}
tran = next;
if (!retain) {
*ext_tran = tran;
tran->detachFromJrdTran();
}
}
}

View File

@ -149,7 +149,7 @@ public:
virtual void attach(Jrd::thread_db *tdbb, const Firebird::string &dbName,
const Firebird::string &user, const Firebird::string &pwd) = 0;
virtual void detach(Jrd::thread_db *tdbb) = 0;
virtual void detach(Jrd::thread_db *tdbb);
int getSqlDialect() const { return m_sqlDialect; }
@ -198,8 +198,12 @@ protected:
virtual Transaction* doCreateTransaction() = 0;
virtual Statement* doCreateStatement() = 0;
void clearTransactions(Jrd::thread_db *tdbb);
void clearStatements(Jrd::thread_db *tdbb);
virtual void doDetach(Jrd::thread_db *tdbb) = 0;
// Protection against simultaneous ISC API calls for the same connection
Firebird::Mutex m_mutex;
@ -253,6 +257,7 @@ public:
protected:
virtual void generateTPB(Jrd::thread_db *tdbb, Firebird::ClumpletWriter &tpb,
TraModes traMode, bool readOnly, bool wait, int lockTimeout) const;
void detachFromJrdTran();
virtual void doStart(ISC_STATUS* status, Jrd::thread_db *tdbb, Firebird::ClumpletWriter &tpb) = 0;
virtual void doPrepare(ISC_STATUS* status, Jrd::thread_db *tdbb, int info_len, const char* info) = 0;
@ -263,6 +268,7 @@ protected:
Connection &m_connection;
TraScope m_scope;
Transaction *m_nextTran; // next common transaction
Jrd::jrd_tra *m_jrdTran; // parent JRD transaction
};

View File

@ -146,11 +146,10 @@ void InternalConnection::attach(thread_db *tdbb, const Firebird::string &dbName,
SQL_DIALECT_V6 : SQL_DIALECT_V5;
}
void InternalConnection::detach(thread_db *tdbb)
void InternalConnection::doDetach(thread_db *tdbb)
{
clearStatements(tdbb);
fb_assert(m_attachment);
if (m_isCurrent)
{
m_attachment = 0;
@ -170,9 +169,10 @@ void InternalConnection::detach(thread_db *tdbb)
}
if (status[1]) {
raise(status, tdbb, "dettach");
raise(status, tdbb, "detach");
}
}
fb_assert(!m_attachment)
}

View File

@ -66,8 +66,6 @@ public:
virtual void attach(Jrd::thread_db *tdbb, const Firebird::string &dbName,
const Firebird::string &user, const Firebird::string &pwd);
virtual void detach(Jrd::thread_db *tdbb);
virtual bool isAvailable(Jrd::thread_db *tdbb, TraScope traScope) const;
virtual bool isConnected() const { return (m_attachment != 0); }
@ -84,6 +82,7 @@ public:
protected:
virtual Transaction* doCreateTransaction();
virtual Statement* doCreateStatement();
virtual void doDetach(Jrd::thread_db *tdbb);
Jrd::Attachment* m_attachment;
bool m_isCurrent;

View File

@ -154,10 +154,8 @@ void IscConnection::attach(thread_db *tdbb, const string &dbName, const string &
}
}
void IscConnection::detach(thread_db *tdbb)
void IscConnection::doDetach(thread_db *tdbb)
{
clearStatements(tdbb);
ISC_STATUS_ARRAY status = {0};
if (m_handle)
{

View File

@ -508,7 +508,6 @@ public:
virtual void attach(Jrd::thread_db *tdbb, const Firebird::string &dbName,
const Firebird::string &user, const Firebird::string &pwd);
virtual void detach(Jrd::thread_db *tdbb);
virtual bool isAvailable(Jrd::thread_db *tdbb, TraScope traScope) const;
@ -519,6 +518,7 @@ public:
protected:
virtual Transaction* doCreateTransaction();
virtual Statement* doCreateStatement();
virtual void doDetach(Jrd::thread_db *tdbb);
IscProvider& m_iscProvider;
FB_API_HANDLE m_handle;

View File

@ -5580,9 +5580,13 @@ static void purge_attachment(thread_db* tdbb,
}
}
const bool wasShuttingDown = engineShuttingDown;
try
{
// allow to free resources used by dynamic statements
engineShuttingDown = false;
EDS::Manager::jrdAttachmentEnd(tdbb, attachment);
engineShuttingDown = wasShuttingDown;
const ULONG att_flags = attachment->att_flags;
attachment->att_flags |= ATT_shutdown;
@ -5601,6 +5605,7 @@ static void purge_attachment(thread_db* tdbb,
}
catch (const Exception&)
{
engineShuttingDown = wasShuttingDown;
attachment->att_flags |= (ATT_shutdown | ATT_purge_error);
throw;
}