Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PDO][MySQL] dziwne zachowanie auto_increment
Forum PHP.pl > Forum > PHP
Fifi209
Przy tworzeniu tabeli dla użytkowników, założyłem że nazwa użytkownika, email i kod weryfikacyjny będą polami unikalnymi. Jeżeli próbuję dodać dane do tabeli, powiedzmy gdzie istnieje już taki mail to dostaję ładny komunikat błędu. Jednak co dziwne, auto_increment się zwiększa ciągle, z każdą nieudaną próbą. Myślałem, że może transakcja to rozwiąże - myliłem się. Czemu się tak dzieje? I czy da się temu zapobiec w inny sposób niż niepotrzebnie wyciągać dane?
cycofiasz
Pokaż strukturę tabeli i kawałek kodu php w którym próbujesz robić inserta.
Czy przez phpMyAdmina też się tak dzieje?
Fifi209
Tak samo dzieje się w phpmyadmin co do struktury

  1.  
  2. -- phpMyAdmin SQL Dump
  3. -- version 3.4.5
  4. -- <a href="http://www.phpmyadmin.net" target="_blank">http://www.phpmyadmin.net</a>
  5. --
  6. -- Host: localhost
  7. -- Czas wygenerowania: 24 Sty 2012, 23:14
  8. -- Wersja serwera: 5.5.16
  9. -- Wersja PHP: 5.3.8
  10.  
  11. SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
  12. SET time_zone = "+00:00";
  13.  
  14.  
  15. /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
  16. /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
  17. /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
  18. /*!40101 SET NAMES utf8 */;
  19.  
  20. --
  21. -- Baza danych: `projekt`
  22. --
  23.  
  24. -- --------------------------------------------------------
  25.  
  26. --
  27. -- Struktura tabeli dla `users`
  28. --
  29.  
  30. CREATE TABLE IF NOT EXISTS `users` (
  31. `id` int(11) NOT NULL AUTO_INCREMENT,
  32. `user` varchar(10) COLLATE utf8_polish_ci NOT NULL,
  33. `passwd` varchar(32) COLLATE utf8_polish_ci NOT NULL,
  34. `ru` int(11) NOT NULL,
  35. `email` varchar(255) COLLATE utf8_polish_ci NOT NULL,
  36. `sent` tinyint(1) NOT NULL,
  37. `race_id` int(11) NOT NULL,
  38. `color` enum('niebieski','czerwony','zielony','żółty','czarny','szary','fioletowy') COLLATE utf8_polish_ci NOT NULL,
  39. `code` varchar(32) COLLATE utf8_polish_ci NOT NULL,
  40. `verified` tinyint(1) NOT NULL,
  41. `last_visited` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  42. PRIMARY KEY (`id`),
  43. UNIQUE KEY `email` (`email`),
  44. UNIQUE KEY `user` (`user`),
  45. UNIQUE KEY `code` (`code`),
  46. KEY `race_id` (`race_id`)
  47. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ;
  48.  
  49. --
  50. -- Ograniczenia dla zrzutów tabel
  51. --
  52.  
  53. --
  54. -- Ograniczenia dla tabeli `users`
  55. --
  56. ALTER TABLE `users`
  57. ADD CONSTRAINT `users_ibfk_12` FOREIGN KEY (`race_id`) REFERENCES `races` (`id`);
  58.  
  59. /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
  60. /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
  61. /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
prowseed
http://dev.mysql.com/doc/refman/5.5/en/inn...t-handling.html

Cytat
When accessing the auto-increment counter, InnoDB uses a special table-level AUTO-INC lock that it keeps to the end of the current SQL statement, not to the end of the transaction. The special lock release strategy was introduced to improve concurrency for inserts into a table containing an AUTO_INCREMENT column. Nevertheless, two transactions cannot have the AUTO-INC lock on the same table simultaneously, which can have a performance impact if the AUTO-INC lock is held for a long time. That might be the case for a statement such as INSERT INTO t1 ... SELECT ... FROM t2 that inserts all rows from one table into another.

InnoDB uses the in-memory auto-increment counter as long as the server runs. When the server is stopped and restarted, InnoDB reinitializes the counter for each table for the first INSERT to the table, as described earlier.

You may see gaps in the sequence of values assigned to the AUTO_INCREMENT column if you roll back transactions that have generated numbers using the counter.


//EDIT
na szybko: ostatnie id to 10, jesli narobilbys blednych insertow, a kolejny (poprawny) insert wsadzil, powiedzmy, po tygodniu (po restarcie serwera) to kolejny id bedzie 11. Jesli wstawiasz insert po blednych probach, to numerek jest zalezny od wartosci przechowywanej w pamieci.
cezet
Korzystasz z PDO? PDO chyba korzysta z transakcji.

Dokładnie nie pamiętam szczegółów, ale jest coś takiego, że kiedy rozpoczynana jest transakcja, i wystąpi błąd (a przynajmniej ROLLBACK, bo co do błędu nie jestem pewien) - to mimo wszystko auto_increment (sekwencja w postgresie) - nie zostanie cofnięta.
Uriziel01
Nie potwierdzam, po rollbacku wszystkie automatyczne indeksy wracają (przynajmniej u mnie) do poprzedniej wartości jak najbardziej poprawnie.
cezet
Dlatego nie jestem pewien, to tylko sugestia.
Tak było w starszej wersji Postgresa wink.gif
Fifi209
Cytat(Uriziel01 @ 25.01.2012, 12:48:41 ) *
Nie potwierdzam, po rollbacku wszystkie automatyczne indeksy wracają (przynajmniej u mnie) do poprzedniej wartości jak najbardziej poprawnie.

A u mnie próbując zrobić to na transakcjach dalej zwiększa, mimo rollback
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.