EDYTUJ:
Edytowano po komentarzu użytkownika do tego posta:
Potrzebujesz blokowanie tabeli zapisu w obu tych dwóch procesach.
Blokada WRITE ma następujące cechy:
-
Jedyna sesja, która utrzymuje blokadę tabeli, może odczytywać i zapisywać dane z tabeli.
-
Inne sesje nie mogą odczytywać i zapisywać danych z tabeli, dopóki blokada WRITE nie zostanie zwolniona.
Zobacz także Unikalne ograniczenie SQL
PRZED EDYCJĄ:
Tak to mozliwe. I zajęło mi trochę czasu, aby to rozgryźć. Opieram to na twoich danych wejściowych i wartościach porównawczych jako test1, test2 itp., gdzie test jest zawsze taki sam i ma końcowy numer. Jak określiłeś.
Można to zrobić jako MYSQL TRANSACTION w 4 krokach.
Powiedzmy, że masz tabelę testT
gdzie nazwa jest unikalna, aby zapewnić, że nie mamy dubletów.
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
I chcesz wstawić nowy element o nazwie test1, którą ustawiliśmy jako:
SET @newName = 'test1';
Następnie musimy sprawdzić, czy już istnieje w tabeli:
SELECT @check:=COUNT(*) FROM testT WHERE name = @newName;
Liczymy tutaj, aby uzyskać prawdę lub fałsz i zapisać to jako @check
tutaj, abyśmy mogli później to porównać. Spowoduje to powstanie 1 row
jako test1
już istnieje w tabeli.
Następnie dokonujemy kolejnego wyboru, aby uzyskać największą liczbę testów* i zapisujemy go jako @number
, to następne zapytanie wybiera wszystkie testy i wykonuje PODŁAŃCUCH po 4 ostatnich, podając nam wszystkie liczby po pierwszych 4 ostatnich. (999999999999) liczby właściwie tylko dla pewności, że nie przegapimy żadnej, ale w naszym przypadku wynik to tylko "3", ponieważ jest to ostatni rekord "test3
" w tabeli.
SELECT
@number:= SUBSTRING(name,5,99999999999)
FROM testT;
Teraz możemy zrobić wstawkę:
INSERT INTO testT(name)
VALUES
(
IF(@check = "", @newName , CONCAT(LEFT(@newName,4),RIGHT(@number,1)+1)
)
);
To próbuje wstawić nasz @newName
do tabeli pod warunkiem JEŻELI, a to oznacza, że nasz @check
jest pusty, wstawi @newName
, jeśli nie, pobierze test słów z ciągu i dołączy najwyższy @number
z wcześniej i dodaj też + 1.
Wynik dla @newName = 'test1'
jest poniżej. Jeśli zmienisz to na @newName = 'test3'
wynik będzie taki sam nowy wstaw test4
.
**Schema (MySQL v5.7)**
SET @newName = 'test1';
---
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test4 |
---
A jeśli zmienisz go w DOWOLNYM teście*, ten numer już nie istnieje, wstawi go normalnie. W poniższym przypadku:@newName = 'test6'
SET @newName = 'test6';
**Query #1**
SELECT * FROM testT
ORDER BY id;
| id | name |
| --- | ----- |
| 1 | test1 |
| 2 | test3 |
| 3 | test6 |
W ten sposób wkładka będzie zawsze wykonana.
Możesz się z tym bawić tutaj:Zobacz na DB Fiddle
po prostu zmieniając SET @newName = 'test6'
Nie jestem ekspertem i zajęło mi kilka godzin, aby znaleźć ten sposób, ponieważ chciałem wiedzieć, czy jest to w ogóle możliwe. I byłbym wdzięczny, gdyby jakikolwiek inny użytkownik mógł zasugerować inny sposób lub ulepszyć moją metodę.