mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-22 20:43:02 +01:00
Added transaction lock timeouts and new TPB value.
This commit is contained in:
parent
863bc63f7c
commit
a4cb9ebc26
@ -2381,13 +2381,12 @@ static bool delete_index(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
index = CMP_get_index_lock(tdbb, relation, id);
|
||||
if (index)
|
||||
{
|
||||
const USHORT wait =
|
||||
(transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
// Try to clear trigger cache to release lock
|
||||
if (index->idl_count)
|
||||
MET_clear_cache(tdbb);
|
||||
if (index->idl_count ||
|
||||
!LCK_lock_non_blocking(tdbb, index->idl_lock, LCK_EX, wait))
|
||||
!LCK_lock_non_blocking(tdbb, index->idl_lock, LCK_EX,
|
||||
transaction->getLockWait()))
|
||||
{
|
||||
ERR_post(isc_no_meta_update,
|
||||
isc_arg_gds, isc_obj_in_use,
|
||||
@ -2530,7 +2529,6 @@ static bool delete_procedure( thread_db* tdbb,
|
||||
*
|
||||
**************************************/
|
||||
jrd_prc* procedure;
|
||||
USHORT wait;
|
||||
USHORT old_flags;
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
@ -2545,9 +2543,8 @@ static bool delete_procedure( thread_db* tdbb,
|
||||
|
||||
if (procedure->prc_existence_lock)
|
||||
{
|
||||
wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
LCK_convert_non_blocking(tdbb, procedure->prc_existence_lock,
|
||||
LCK_SR, wait);
|
||||
LCK_SR, transaction->getLockWait());
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -2564,9 +2561,8 @@ static bool delete_procedure( thread_db* tdbb,
|
||||
|
||||
if (procedure->prc_existence_lock)
|
||||
{
|
||||
wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
if (!LCK_convert_non_blocking(tdbb, procedure->prc_existence_lock,
|
||||
LCK_EX, wait))
|
||||
LCK_EX, transaction->getLockWait()))
|
||||
{
|
||||
ERR_post(isc_no_meta_update,
|
||||
isc_arg_gds, isc_obj_in_use,
|
||||
@ -2645,7 +2641,7 @@ static bool delete_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
jrd_req* request;
|
||||
jrd_rel* relation;
|
||||
Resource* rsc;
|
||||
USHORT wait, view_count;
|
||||
USHORT view_count;
|
||||
bool adjusted;
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
@ -2661,9 +2657,8 @@ static bool delete_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
|
||||
if (relation->rel_existence_lock)
|
||||
{
|
||||
wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
LCK_convert_non_blocking(tdbb, relation->rel_existence_lock,
|
||||
LCK_SR, wait);
|
||||
LCK_SR, transaction->getLockWait());
|
||||
}
|
||||
|
||||
relation->rel_flags &= ~REL_deleting;
|
||||
@ -2723,13 +2718,12 @@ static bool delete_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
}
|
||||
}
|
||||
|
||||
wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
if (relation->rel_use_count)
|
||||
MET_clear_cache(tdbb);
|
||||
if (relation->rel_use_count ||
|
||||
(relation->rel_existence_lock &&
|
||||
!LCK_convert_non_blocking(tdbb, relation->rel_existence_lock,
|
||||
LCK_EX, wait)))
|
||||
LCK_EX, transaction->getLockWait())))
|
||||
{
|
||||
if (adjusted) {
|
||||
++relation->rel_use_count;
|
||||
@ -2761,7 +2755,7 @@ static bool delete_relation(thread_db* tdbb, SSHORT phase, DeferredWork* work,
|
||||
don't wait forever if something has gone awry and the sweep
|
||||
count doesn't run down. */
|
||||
|
||||
for (wait = 0; wait < 60; wait++)
|
||||
for (int wait = 0; wait < 60; wait++)
|
||||
{
|
||||
if (!relation->rel_sweep_count) {
|
||||
break;
|
||||
@ -3830,7 +3824,6 @@ static bool modify_procedure( thread_db* tdbb,
|
||||
*
|
||||
**************************************/
|
||||
jrd_prc* procedure;
|
||||
USHORT wait;
|
||||
|
||||
SET_TDBB(tdbb);
|
||||
|
||||
@ -3849,9 +3842,8 @@ static bool modify_procedure( thread_db* tdbb,
|
||||
|
||||
if (procedure->prc_existence_lock)
|
||||
{
|
||||
wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
LCK_convert_non_blocking(tdbb, procedure->prc_existence_lock,
|
||||
LCK_SR, wait);
|
||||
LCK_SR, transaction->getLockWait());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -3869,12 +3861,10 @@ static bool modify_procedure( thread_db* tdbb,
|
||||
|
||||
if (procedure->prc_existence_lock)
|
||||
{
|
||||
wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
|
||||
/* Let relation be deleted if only this transaction is using it */
|
||||
|
||||
if (!LCK_convert_non_blocking(tdbb, procedure->prc_existence_lock,
|
||||
LCK_EX, wait))
|
||||
LCK_EX, transaction->getLockWait()))
|
||||
{
|
||||
ERR_post(isc_no_meta_update,
|
||||
isc_arg_gds, isc_obj_in_use,
|
||||
|
@ -33,7 +33,7 @@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
$Id: ibase.h,v 1.87 2004-09-22 01:59:20 robocop Exp $
|
||||
$Id: ibase.h,v 1.88 2004-09-28 20:25:52 dimitr Exp $
|
||||
*/
|
||||
|
||||
#ifndef JRD_IBASE_H
|
||||
@ -1292,12 +1292,13 @@ int ISC_EXPORT isc_get_client_minor_version ();
|
||||
#define isc_tpb_verb_time 12
|
||||
#define isc_tpb_commit_time 13
|
||||
#define isc_tpb_ignore_limbo 14
|
||||
#define isc_tpb_read_committed 15
|
||||
#define isc_tpb_autocommit 16
|
||||
#define isc_tpb_rec_version 17
|
||||
#define isc_tpb_no_rec_version 18
|
||||
#define isc_tpb_restart_requests 19
|
||||
#define isc_tpb_read_committed 15
|
||||
#define isc_tpb_autocommit 16
|
||||
#define isc_tpb_rec_version 17
|
||||
#define isc_tpb_no_rec_version 18
|
||||
#define isc_tpb_restart_requests 19
|
||||
#define isc_tpb_no_auto_undo 20
|
||||
#define isc_tpb_lock_timeout 21
|
||||
|
||||
|
||||
/************************/
|
||||
|
@ -257,11 +257,10 @@ Lock* RLCK_range_relation(jrd_tra* transaction,
|
||||
|
||||
const USHORT level = LCK_PR;
|
||||
|
||||
const USHORT wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
|
||||
/* get lock */
|
||||
|
||||
const USHORT result = LCK_lock_non_blocking(tdbb, lock, level, wait);
|
||||
const USHORT result =
|
||||
LCK_lock_non_blocking(tdbb, lock, level, transaction->getLockWait());
|
||||
|
||||
if (result)
|
||||
return lock;
|
||||
@ -440,18 +439,19 @@ Lock* RLCK_reserve_relation(thread_db* tdbb,
|
||||
return lock;
|
||||
if (transaction->tra_flags & TRA_reserving)
|
||||
ERR_post(isc_unres_rel, isc_arg_string, relation->rel_name, 0);
|
||||
const USHORT wait = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
/* get lock */
|
||||
USHORT result;
|
||||
if (lock->lck_logical)
|
||||
result = LCK_convert_non_blocking(NULL, lock, level, wait);
|
||||
result = LCK_convert_non_blocking(NULL, lock, level,
|
||||
transaction->getLockWait());
|
||||
else
|
||||
result = LCK_lock_non_blocking(NULL, lock, level, wait);
|
||||
result = LCK_lock_non_blocking(NULL, lock, level,
|
||||
transaction->getLockWait());
|
||||
if (result)
|
||||
return lock;
|
||||
else {
|
||||
if (error_flag)
|
||||
ERR_post((wait) ? isc_deadlock : isc_lock_conflict, 0);
|
||||
ERR_post(transaction->getLockWait() ? isc_deadlock : isc_lock_conflict, 0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -964,7 +964,7 @@ static bool obtain_lock(jrd_tra* transaction, Lock* lock, USHORT lock_level)
|
||||
**************************************/
|
||||
USHORT wait_flag;
|
||||
if (transaction)
|
||||
wait_flag = (transaction->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
wait_flag = transaction->getLockWait();
|
||||
else
|
||||
wait_flag = FALSE;
|
||||
/* return if lock level OK and if the lock has not been released
|
||||
|
@ -90,9 +90,15 @@ static const SCHAR lock_types[] =
|
||||
};
|
||||
#endif /* VMS */
|
||||
|
||||
const int DEFAULT_LOCK_TIMEOUT = -1;
|
||||
|
||||
using namespace Jrd;
|
||||
using namespace Ods;
|
||||
|
||||
SSHORT jrd_tra::getLockWait() const
|
||||
{
|
||||
return (tra_flags & TRA_nowait) ? 0 : -tra_lock_timeout;
|
||||
}
|
||||
|
||||
#ifdef SUPERSERVER_V2
|
||||
static SLONG bump_transaction_id(thread_db*, WIN *);
|
||||
@ -686,6 +692,7 @@ void TRA_init(thread_db* tdbb)
|
||||
|
||||
jrd_tra* trans = FB_NEW_RPT(*dbb->dbb_permanent, 0) jrd_tra(*dbb->dbb_permanent);
|
||||
dbb->dbb_sys_trans = trans;
|
||||
trans->tra_lock_timeout = DEFAULT_LOCK_TIMEOUT;
|
||||
trans->tra_flags |= TRA_system | TRA_ignore_limbo;
|
||||
trans->tra_pool = dbb->dbb_permanent;
|
||||
}
|
||||
@ -939,6 +946,7 @@ jrd_tra* TRA_reconnect(thread_db* tdbb, const UCHAR* id, USHORT length)
|
||||
jrd_tra* trans = FB_NEW_RPT(*tdbb->getDefaultPool(), 0) jrd_tra(*tdbb->getDefaultPool());
|
||||
trans->tra_pool = tdbb->getDefaultPool();
|
||||
trans->tra_number = gds__vax_integer(id, length);
|
||||
trans->tra_lock_timeout = DEFAULT_LOCK_TIMEOUT;
|
||||
trans->tra_flags |= TRA_prepared | TRA_reconnected | TRA_write;
|
||||
|
||||
const UCHAR state = limbo_transaction(tdbb, trans->tra_number);
|
||||
@ -1478,6 +1486,7 @@ jrd_tra* TRA_start(thread_db* tdbb, int tpb_length, const SCHAR* tpb)
|
||||
|
||||
trans->tra_pool = temp->tra_pool;
|
||||
trans->tra_relation_locks = temp->tra_relation_locks;
|
||||
trans->tra_lock_timeout = temp->tra_lock_timeout;
|
||||
trans->tra_flags = temp->tra_flags;
|
||||
trans->tra_number = number;
|
||||
trans->tra_top = number;
|
||||
@ -1971,8 +1980,8 @@ int TRA_wait(thread_db* tdbb, jrd_tra* trans, SLONG number, bool wait)
|
||||
temp_lock.lck_key.lck_long = number;
|
||||
temp_lock.lck_owner = trans;
|
||||
|
||||
const USHORT wait_flag = (trans->tra_flags & TRA_nowait) ? FALSE : TRUE;
|
||||
if (!LCK_lock_non_blocking(tdbb, &temp_lock, LCK_read, wait_flag))
|
||||
if (!LCK_lock_non_blocking(tdbb, &temp_lock, LCK_read,
|
||||
trans->getLockWait()))
|
||||
return tra_active;
|
||||
|
||||
LCK_release(tdbb, &temp_lock);
|
||||
@ -2767,12 +2776,13 @@ static void transaction_options(
|
||||
if (!tpb_length)
|
||||
return;
|
||||
|
||||
USHORT wait = 1;
|
||||
const UCHAR* const end = tpb + tpb_length;
|
||||
|
||||
if (*tpb != isc_tpb_version3 && *tpb != isc_tpb_version1)
|
||||
ERR_post(isc_bad_tpb_form, isc_arg_gds, isc_wrotpbver, 0);
|
||||
|
||||
transaction->tra_lock_timeout = DEFAULT_LOCK_TIMEOUT;
|
||||
|
||||
++tpb;
|
||||
|
||||
while (tpb < end) {
|
||||
@ -2810,7 +2820,6 @@ static void transaction_options(
|
||||
break;
|
||||
|
||||
case isc_tpb_nowait:
|
||||
wait = 0;
|
||||
transaction->tra_flags |= TRA_nowait;
|
||||
break;
|
||||
|
||||
@ -2838,7 +2847,7 @@ static void transaction_options(
|
||||
USHORT l = *tpb++;
|
||||
if (l) {
|
||||
if (l >= sizeof(name)) {
|
||||
TEXT text[128];
|
||||
TEXT text[BUFFER_TINY];
|
||||
USHORT flags = 0;
|
||||
gds__msg_lookup(0, DYN_MSG_FAC, 159, sizeof(text),
|
||||
text, &flags);
|
||||
@ -2893,6 +2902,14 @@ static void transaction_options(
|
||||
transaction->tra_flags |= TRA_restart_requests;
|
||||
break;
|
||||
|
||||
case isc_tpb_lock_timeout:
|
||||
{
|
||||
const USHORT l = *tpb++;
|
||||
transaction->tra_lock_timeout = gds__vax_integer(tpb, l);
|
||||
tpb += l;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ERR_post(isc_bad_tpb_form, 0);
|
||||
}
|
||||
@ -2912,6 +2929,7 @@ static void transaction_options(
|
||||
if (!lock)
|
||||
continue;
|
||||
USHORT level = lock->lck_logical;
|
||||
const SSHORT wait = transaction->getLockWait();
|
||||
if (level == LCK_none
|
||||
|| LCK_lock_non_blocking(tdbb, lock, level, wait))
|
||||
{
|
||||
|
@ -105,8 +105,11 @@ class jrd_tra : public pool_alloc_rpt<SCHAR, type_tra>
|
||||
traRpbList* tra_rpblist; /* active record_param's of given transaction */
|
||||
UCHAR tra_use_count; /* use count for safe AST delivery */
|
||||
UCHAR tra_callback_count; /* callback count for 'execute statement' */
|
||||
SSHORT tra_lock_timeout; /* in seconds, -1 infinite */
|
||||
ULONG tra_next_blob_id; // ID of the previous blob or array created in this transaction
|
||||
UCHAR tra_transactions[1];
|
||||
|
||||
SSHORT getLockWait() const;
|
||||
};
|
||||
|
||||
const ULONG TRA_system = 1L; /* system transaction */
|
||||
|
Loading…
Reference in New Issue
Block a user