8
0
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:
dimitr 2004-09-28 20:25:52 +00:00
parent 863bc63f7c
commit a4cb9ebc26
5 changed files with 51 additions and 39 deletions

View File

@ -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,

View File

@ -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
/************************/

View File

@ -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

View File

@ -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))
{

View File

@ -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 */