type_mode基础上 加上 LOCK_WAIT 表示等待状态
/*********************************************************************//** Enqueues a waiting request for a lock which cannot be granted immediately. Checks for deadlocks. @return DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED, or DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that there was a deadlock, but another transaction was chosen as a victim, and we got the lock immediately: no need to wait then */ static enum db_err lock_rec_enqueue_waiting( /*=====================*/ ulint type_mode,/*!< in: lock mode this transaction is requesting: LOCK_S or LOCK_X, possibly ORed with LOCK_GAP or LOCK_REC_NOT_GAP, ORed with LOCK_INSERT_INTENTION if this waiting lock request is set when performing an insert of an index record */ const buf_block_t* block, /*!< in: buffer block containing the record */ ulint heap_no,/*!< in: heap number of the record */ lock_t* lock, /*!< in: lock object; NULL if a new one should be created. */ dict_index_t* index, /*!< in: index of record */ que_thr_t* thr) /*!< in: query thread */ { trx_t* trx; ut_ad(mutex_own(&kernel_mutex)); /* Test if there already is some other reason to suspend thread: we do not enqueue a lock request if the query thread should be stopped anyway */ if (UNIV_UNLIKELY(que_thr_stop(thr))) { ut_error; return(DB_QUE_THR_SUSPENDED); } trx = thr_get_trx(thr); switch (trx_get_dict_operation(trx)) { case TRX_DICT_OP_NONE: break; case TRX_DICT_OP_TABLE: case TRX_DICT_OP_INDEX: ut_print_timestamp(stderr); fputs(" InnoDB: Error: a record lock wait happens" " in a dictionary operation!\n" "InnoDB: ", stderr); dict_index_name_print(stderr, trx, index); fputs(".\n" "InnoDB: Submit a detailed bug report" " to http://bugs.mysql.com\n", stderr); ut_ad(); } if (lock == NULL) { /* Enqueue the lock request that will wait to be granted */ lock = lock_rec_create(type_mode | LOCK_WAIT, block, heap_no, index, trx); } else { ut_ad(lock->type_mode & LOCK_WAIT); ut_ad(lock->type_mode & LOCK_CONV_BY_OTHER); lock->type_mode &= ~LOCK_CONV_BY_OTHER; lock_set_lock_and_trx_wait(lock, trx); } /* Check if a deadlock occurs: if yes, remove the lock request and return an error code */ if (UNIV_UNLIKELY(lock_deadlock_occurs(lock, trx))) { lock_reset_lock_and_trx_wait(lock); lock_rec_reset_nth_bit(lock, heap_no); return(DB_DEADLOCK); } /* If there was a deadlock but we chose another transaction as a victim, it is possible that we already have the lock now granted! */ if (trx->wait_lock == NULL) { return(DB_SUCCESS_LOCKED_REC); } trx->que_state = TRX_QUE_LOCK_WAIT; trx->was_chosen_as_deadlock_victim = FALSE; trx->wait_started = time(NULL); ut_a(que_thr_stop(thr)); #ifdef UNIV_DEBUG if (lock_print_waits) { fprintf(stderr, "Lock wait for trx " TRX_ID_FMT " in index ", (ullint) trx->id); ut_print_name(stderr, trx, FALSE, index->name); } #endif /* UNIV_DEBUG */ return(DB_LOCK_WAIT); }