РЕДАКТИРОВАТЬ:
Отредактировано после комментария пользователя к этому сообщению:
Вам необходимо запись блокировки таблицы в обоих этих процессах.
Блокировка WRITE имеет следующие функции:
Единственный сеанс, который удерживает блокировку таблицы, может считывать и записывать данные из таблицы.
Другие сеансы не могут считывать данные и записывать данные в таблицу, пока не будет снята блокировка WRITE.
Также посмотрите на SQL UNIQUE Constraint
ДО РЕДАКТИРОВАНИЯ:
Да, это возможно. И мне потребовалось некоторое время, чтобы понять это. Я строю это на ваших входных и сравниваемых значениях как test1, test2 et c, где test всегда одинаков и имеет конечный номер. Как вы указали.
Это можно сделать как MySQL СДЕЛКА в 4 этапа.
Допустим, у вас есть таблица testT
, где имя уникально, чтобы гарантировать, что у нас нет двойников.
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
И вы хотите вставить новый элемент с именем test1, которое мы установили следующим образом:
SET @newName = 'test1';
Затем нам нужно проверить, существует ли он уже в таблице:
SELECT @check:=COUNT(*) FROM testT WHERE name = @newName;
Мы делаем подсчет здесь, чтобы получить значение true или false и сохранить его как @check
здесь, чтобы мы могли сравнить его позже. Это приведет к 1 row
, так как test1
уже существует в таблице.
Затем мы делаем другой выбор, чтобы получить наибольшее количество тестов * и сохранить его как @number
, этот следующий запрос выбирает все тесты и делает SUBSTRING после 4 последних, давая нам все числа после первых 4 последних. (99999999999) числа на самом деле просто для того, чтобы быть уверенными, что мы не пропустили ни одного, но в нашем случае результат - только «3», потому что это последняя запись «test3
» в таблице.
SELECT
@number:= SUBSTRING(name,5,99999999999)
FROM testT;
Теперь мы можем сделать вставку:
INSERT INTO testT(name)
VALUES
(
IF(@check = "", @newName , CONCAT(LEFT(@newName,4),RIGHT(@number,1)+1)
)
);
Это пытается вставить наш @newName
в таблицу при условии IF, и если наш @check
пуст, то он вставит @newName
, если нет, то он возьмет слово test из строки, добавит наивысший @number
из предыдущего и добавит + 1 к нему.
Таким образом, результат для @newName = 'test1'
ниже. Если вы измените это на @newName = 'test3'
результат будет такой же новой вставкой test4
.
**Schema (MySQL v5.7)**
SET @newName = 'test1';
---
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test4 |
---
И если вы измените его в ЛЮБОМ тесте *, то это число еще не существует, оно вставит его как обычно. В случае ниже: @newName = 'test6'
SET @newName = 'test6';
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test6 |
Таким образом, вставка всегда будет сделана.
Вы можете поиграть с этим здесь: Посмотреть на БД Fiddle просто изменив SET @newName = 'test6'
Я не эксперт, и мне понадобилось несколько часов, чтобы понять это из, как я хотел знать, было ли это вообще возможно. И я был бы признателен, если какой-либо другой пользователь может предложить другой способ или улучшить мой метод.