diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 79da2b522d7..aa463e5fed2 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -1679,6 +1679,9 @@ row_sel(
 	plan = sel_node_get_nth_plan(node, node->fetch_table);
 	index = plan->index;
 
+	bool table_locked = lock_table_locked(trx, index->table,
+	    node->row_lock_mode);
+
 	if (plan->n_rows_prefetched > 0) {
 		sel_dequeue_prefetched_row(plan);
 
@@ -1785,7 +1788,7 @@ row_sel(
 		and it might be that these new records should appear in the
 		search result set, resulting in the phantom problem. */
 
-		if (!node->read_view) {
+		if (!table_locked && !node->read_view) {
 			rec_t*	next_rec = page_rec_get_next(rec);
 			unsigned lock_type;
 
@@ -1845,7 +1848,8 @@ row_sel(
 		goto next_rec;
 	}
 
-	if (!node->read_view) {
+	if (!table_locked
+	    && !node->read_view) {
 		/* Try to place a lock on the index record */
 		unsigned lock_type;
 
@@ -3455,7 +3459,9 @@ Row_sel_get_clust_rec_for_mysql::operator()(
 				   clust_index->n_core_fields,
 				   ULINT_UNDEFINED, offset_heap);
 
-	if (prebuilt->select_lock_type != LOCK_NONE) {
+	if (prebuilt->select_lock_type != LOCK_NONE
+	    && !lock_table_locked(trx, clust_index->table,
+	      prebuilt->select_lock_type)) {
 		/* Try to place a lock on the index record; we are searching
 		the clust rec with a unique condition, hence
 		we set a LOCK_REC_NOT_GAP type lock */
@@ -4485,6 +4491,10 @@ row_search_mvcc(
 	rec_offs*	offsets				= offsets_;
 	rec_offs_init(offsets_);
 
+	bool table_locked = prebuilt->select_lock_type != LOCK_NONE
+	  && lock_table_locked(trx, prebuilt->table,
+	    prebuilt->select_lock_type);
+
 #ifdef BTR_CUR_HASH_ADAPT
 	/*-------------------------------------------------------------*/
 	/* PHASE 2: Try fast adaptive hash index search if possible */
@@ -4629,6 +4639,7 @@ row_search_mvcc(
 	isolation level */
 	const bool set_also_gap_locks =
 		prebuilt->select_lock_type != LOCK_NONE
+		&& !table_locked
 		&& trx->isolation_level > TRX_ISO_READ_COMMITTED
 #ifdef WITH_WSREP
 		&& !wsrep_thd_skip_locking(trx->mysql_thd)
@@ -4658,6 +4669,7 @@ row_search_mvcc(
 
 	if (prebuilt->table->no_rollback()) {
 		/* NO_ROLLBACK tables do not support MVCC or locking. */
+		table_locked = true;
 		prebuilt->select_lock_type = LOCK_NONE;
 		prebuilt->sql_stat_start = FALSE;
 	} else if (!prebuilt->sql_stat_start) {
@@ -4668,7 +4680,7 @@ row_search_mvcc(
 		prebuilt->sql_stat_start = FALSE;
 		trx_start_if_not_started(trx, false);
 
-		if (prebuilt->select_lock_type == LOCK_NONE) {
+		if (prebuilt->select_lock_type == LOCK_NONE || table_locked) {
 			trx->read_view.open(trx);
 		} else {
 wait_table_again:
@@ -5093,7 +5105,7 @@ row_search_mvcc(
 	/* We are ready to look at a possible new index entry in the result
 	set: the cursor is now placed on a user record */
 
-	if (prebuilt->select_lock_type != LOCK_NONE) {
+	if (prebuilt->select_lock_type != LOCK_NONE && !table_locked) {
 		/* Try to place a lock on the index record; note that delete
 		marked records are a special case in a unique search. If there
 		is a non-delete marked record, then it is enough to lock its
@@ -5284,7 +5296,7 @@ row_search_mvcc(
 
 			goto lock_wait_or_error;
 		}
-	} else {
+	} else if (!table_locked) {
 		/* This is a non-locking consistent read: if necessary, fetch
 		a previous version of the record */
 
@@ -5463,6 +5475,7 @@ row_search_mvcc(
 			if (clust_rec == NULL) {
 				/* The record did not exist in the read view */
 				ut_ad(prebuilt->select_lock_type == LOCK_NONE
+				      || table_locked
 				      || dict_index_is_spatial(index));
 
 				goto next_rec;
