diff options
-rw-r--r-- | innobase/include/lock0lock.h | 27 | ||||
-rw-r--r-- | innobase/lock/lock0lock.c | 42 | ||||
-rw-r--r-- | innobase/row/row0ins.c | 8 |
3 files changed, 71 insertions, 6 deletions
diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index b99359fe998..e533ac08545 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -345,6 +345,33 @@ lock_clust_rec_read_check_and_lock( LOCK_REC_NOT_GAP */ que_thr_t* thr); /* in: query thread */ /************************************************************************* +Checks if locks of other transactions prevent an immediate read, or passing +over by a read cursor, of a clustered index record. If they do, first tests +if the query thread should anyway be suspended for some reason; if not, then +puts the transaction and the query thread to the lock wait state and inserts a +waiting request for a record lock to the lock queue. Sets the requested mode +lock on the record. This is an alternative version of +lock_clust_rec_read_check_and_lock() that does not require the parameter +"offsets". */ + +ulint +lock_clust_rec_read_check_and_lock_alt( +/*===================================*/ + /* out: DB_SUCCESS, DB_LOCK_WAIT, + DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ + ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, + does nothing */ + rec_t* rec, /* in: user record or page supremum record + which should be read or passed over by a read + cursor */ + dict_index_t* index, /* in: clustered index */ + ulint mode, /* in: mode of the lock which the read cursor + should set on records: LOCK_S or LOCK_X; the + latter is possible in SELECT FOR UPDATE */ + ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or + LOCK_REC_NOT_GAP */ + que_thr_t* thr); /* in: query thread */ +/************************************************************************* Checks that a record is seen in a consistent read. */ ibool diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 961210dbd06..70075019389 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -5105,3 +5105,45 @@ lock_clust_rec_read_check_and_lock( return(err); } +/************************************************************************* +Checks if locks of other transactions prevent an immediate read, or passing +over by a read cursor, of a clustered index record. If they do, first tests +if the query thread should anyway be suspended for some reason; if not, then +puts the transaction and the query thread to the lock wait state and inserts a +waiting request for a record lock to the lock queue. Sets the requested mode +lock on the record. This is an alternative version of +lock_clust_rec_read_check_and_lock() that does not require the parameter +"offsets". */ + +ulint +lock_clust_rec_read_check_and_lock_alt( +/*===================================*/ + /* out: DB_SUCCESS, DB_LOCK_WAIT, + DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */ + ulint flags, /* in: if BTR_NO_LOCKING_FLAG bit is set, + does nothing */ + rec_t* rec, /* in: user record or page supremum record + which should be read or passed over by a read + cursor */ + dict_index_t* index, /* in: clustered index */ + ulint mode, /* in: mode of the lock which the read cursor + should set on records: LOCK_S or LOCK_X; the + latter is possible in SELECT FOR UPDATE */ + ulint gap_mode,/* in: LOCK_ORDINARY, LOCK_GAP, or + LOCK_REC_NOT_GAP */ + que_thr_t* thr) /* in: query thread */ +{ + mem_heap_t* tmp_heap = NULL; + ulint offsets_[100] = { 100, }; + ulint* offsets = offsets_; + ulint ret; + + offsets = rec_get_offsets(rec, index, offsets, + ULINT_UNDEFINED, &tmp_heap); + ret = lock_clust_rec_read_check_and_lock(flags, rec, index, + offsets, mode, gap_mode, thr); + if (tmp_heap) { + mem_heap_free(tmp_heap); + } + return(ret); +} diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 969c3341be3..8b19f9d9a11 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -717,8 +717,6 @@ row_ins_foreign_check_on_constraint( ulint i; trx_t* trx; mem_heap_t* tmp_heap = NULL; - ulint offsets_[100] = { 100, }; - ulint* offsets = offsets_; ut_a(thr && foreign && pcur && mtr); @@ -886,10 +884,8 @@ row_ins_foreign_check_on_constraint( we already have a normal shared lock on the appropriate gap if the search criterion was not unique */ - offsets = rec_get_offsets(clust_rec, clust_index, offsets, - ULINT_UNDEFINED, &tmp_heap); - err = lock_clust_rec_read_check_and_lock(0, clust_rec, - clust_index, offsets, LOCK_X, LOCK_REC_NOT_GAP, thr); + err = lock_clust_rec_read_check_and_lock_alt(0, clust_rec, + clust_index, LOCK_X, LOCK_REC_NOT_GAP, thr); } if (err != DB_SUCCESS) { |