8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:43:02 +01:00

Fixed bug #7103 : FB service hangs and can not be stopped after several 'DELETE FROM MON$STATEMENTS' being issued in order to stop ES/EDS which waits record for updating.

This commit is contained in:
Vlad Khorsun 2022-01-26 17:06:43 +02:00
parent b2f196257c
commit efd5f6a7e1
2 changed files with 45 additions and 33 deletions

View File

@ -126,24 +126,6 @@ InternalConnection::~InternalConnection()
{
}
// Status helper
class IntStatus : public Firebird::FbLocalStatus
{
public:
explicit IntStatus(FbStatusVector *p)
: FbLocalStatus(), v(p)
{}
~IntStatus()
{
if (v)
fb_utils::copyStatus(v, &(*this));
}
private:
FbStatusVector *v;
};
void InternalConnection::attach(thread_db* tdbb)
{
fb_assert(!m_attachment);
@ -344,10 +326,9 @@ void InternalTransaction::doStart(FbStatusVector* status, thread_db* tdbb, Clump
JAttachment* att = m_IntConnection.getJrdAtt();
EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION);
IntStatus s(status);
m_transaction.assignRefNoIncr(
att->startTransaction(&s, tpb.getBufferLength(), tpb.getBuffer()));
att->startTransaction(status, tpb.getBufferLength(), tpb.getBuffer()));
if (m_transaction)
m_transaction->getHandle()->tra_callback_count = localTran->tra_callback_count;
@ -373,15 +354,13 @@ void InternalTransaction::doCommit(FbStatusVector* status, thread_db* tdbb, bool
}
else
{
IntStatus s(status);
EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION);
if (retain)
m_transaction->commitRetaining(&s);
m_transaction->commitRetaining(status);
else
{
m_transaction->commit(&s);
if (!(s->getState() & IStatus::STATE_ERRORS))
m_transaction->commit(status);
if (!(status->getState() & IStatus::STATE_ERRORS))
m_transaction.clear();
}
}
@ -402,23 +381,40 @@ void InternalTransaction::doRollback(FbStatusVector* status, thread_db* tdbb, bo
if (!retain) {
m_transaction = NULL; // release and nullify
}
return;
}
else
{
IntStatus s(status);
ISC_STATUS err = 0;
{
EngineCallbackGuard guard(tdbb, *this, FB_FUNCTION);
if (retain)
m_transaction->rollbackRetaining(&s);
m_transaction->rollbackRetaining(status);
else
m_transaction->rollback(status);
if (status->getState() & IStatus::STATE_ERRORS)
err = status->getErrors()[1];
if (err == isc_cancelled)
{
m_transaction->rollback(&s);
if (!(s->getState() & IStatus::STATE_ERRORS))
m_transaction.clear();
FbLocalStatus temp;
JAttachment* jAtt = m_IntConnection.getJrdAtt();
jAtt->cancelOperation(&temp, fb_cancel_disable);
status->init();
if (retain)
m_transaction->rollbackRetaining(status);
else
m_transaction->rollback(status);
err = (status->getState() & IStatus::STATE_ERRORS) ?
status->getErrors()[1] : 0;
jAtt->cancelOperation(&temp, fb_cancel_enable);
}
}
if ((status->getErrors()[1] == isc_att_shutdown || status->getErrors()[1] == isc_shutdown) && !retain)
if ((!err || err == isc_att_shutdown || err == isc_shutdown) && !retain)
{
m_transaction.clear();
status->init();

View File

@ -396,6 +396,22 @@ void IscTransaction::doRollback(FbStatusVector* status, thread_db* tdbb, bool re
else
m_iscProvider.isc_rollback_transaction(status, &m_handle);
if ((status->getState() & IStatus::STATE_ERRORS) &&
(status->getErrors()[1] == isc_cancelled))
{
FbLocalStatus temp;
FB_API_HANDLE db = m_iscConnection.getAPIHandle();
m_iscProvider.fb_cancel_operation(&temp, &db, fb_cancel_disable);
status->init();
if (retain)
m_iscProvider.isc_rollback_retaining(status, &m_handle);
else
m_iscProvider.isc_rollback_transaction(status, &m_handle);
m_iscProvider.fb_cancel_operation(&temp, &db, fb_cancel_enable);
}
if ((status->getState() & IStatus::STATE_ERRORS) &&
isConnectionBrokenError(status) && !retain)
{