mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 02:03:04 +01:00
Postfix for #7446: never attempt to delete savepoints belonging to a different transaction
This commit is contained in:
parent
914fded635
commit
9dc3f5e6cc
@ -3712,6 +3712,7 @@ const StmtNode* InAutonomousTransactionNode::execute(thread_db* tdbb, jrd_req* r
|
||||
org_transaction->tra_lock_timeout,
|
||||
org_transaction);
|
||||
|
||||
request->pushTransaction(org_transaction);
|
||||
TRA_attach_request(transaction, request);
|
||||
tdbb->setTransaction(transaction);
|
||||
|
||||
@ -3722,12 +3723,13 @@ const StmtNode* InAutonomousTransactionNode::execute(thread_db* tdbb, jrd_req* r
|
||||
}
|
||||
catch (Exception&)
|
||||
{
|
||||
TRA_detach_request(request);
|
||||
request->popTransaction();
|
||||
TRA_attach_request(org_transaction, request);
|
||||
tdbb->setTransaction(org_transaction);
|
||||
throw;
|
||||
}
|
||||
|
||||
request->req_auto_trans.push(org_transaction);
|
||||
impure->traNumber = transaction->tra_number;
|
||||
|
||||
VIO_start_save_point(tdbb, transaction);
|
||||
@ -3841,8 +3843,11 @@ const StmtNode* InAutonomousTransactionNode::execute(thread_db* tdbb, jrd_req* r
|
||||
}
|
||||
|
||||
impure->traNumber = impure->savNumber = 0;
|
||||
transaction = request->req_auto_trans.pop();
|
||||
|
||||
// Normally request is detached by commit/rollback, but they may fail.
|
||||
// It should be done before request->popTransaction().
|
||||
TRA_detach_request(request);
|
||||
transaction = request->popTransaction();
|
||||
TRA_attach_request(transaction, request);
|
||||
tdbb->setTransaction(transaction);
|
||||
|
||||
|
@ -164,6 +164,21 @@ private:
|
||||
|
||||
class jrd_req : public pool_alloc<type_req>
|
||||
{
|
||||
// Context data saved/restored with every new autonomous transaction
|
||||
|
||||
struct AutoTranCtx
|
||||
{
|
||||
AutoTranCtx() : m_transaction(NULL), m_savepoints(NULL)
|
||||
{}
|
||||
|
||||
AutoTranCtx(jrd_tra* tran, Savepoint* save) :
|
||||
m_transaction(tran), m_savepoints(save)
|
||||
{}
|
||||
|
||||
jrd_tra* m_transaction;
|
||||
Savepoint* m_savepoints;
|
||||
};
|
||||
|
||||
public:
|
||||
jrd_req(Attachment* attachment, /*const*/ JrdStatement* aStatement,
|
||||
Firebird::MemoryStats* parent_stats)
|
||||
@ -263,7 +278,7 @@ public:
|
||||
ULONG req_src_column;
|
||||
|
||||
dsc* req_domain_validation; // Current VALUE for constraint validation
|
||||
Firebird::Stack<jrd_tra*> req_auto_trans; // Autonomous transactions
|
||||
Firebird::Stack<AutoTranCtx> req_auto_trans; // Autonomous transactions
|
||||
SortOwner req_sorts;
|
||||
Firebird::Array<record_param> req_rpb; // record parameter blocks
|
||||
Firebird::Array<UCHAR> impureArea; // impure area
|
||||
@ -294,6 +309,24 @@ public:
|
||||
}
|
||||
req_base_stats.assign(req_stats);
|
||||
}
|
||||
|
||||
// Save context when switching to the autonomous transaction
|
||||
void pushTransaction(jrd_tra* const transaction)
|
||||
{
|
||||
req_auto_trans.push(AutoTranCtx(transaction, req_proc_sav_point));
|
||||
req_proc_sav_point = NULL;
|
||||
}
|
||||
|
||||
// Restore context
|
||||
jrd_tra* popTransaction()
|
||||
{
|
||||
fb_assert(!req_transaction); // must be detached
|
||||
|
||||
const AutoTranCtx tmp = req_auto_trans.pop();
|
||||
req_proc_sav_point = tmp.m_savepoints;
|
||||
|
||||
return tmp.m_transaction;
|
||||
}
|
||||
};
|
||||
|
||||
// Flags for req_flags
|
||||
|
Loading…
Reference in New Issue
Block a user