Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]Numeracja dok a pętla
Forum PHP.pl > Forum > Przedszkole
Randallmaster
Cześć, mam problem z ustaleniem działania funkcjonalności... a mianowicie. w pętli wykonuje pobranie numeru dokumentu, który póżniej zapisuje. Natomiast po zapisaniu dublują mi się numeracja i nie dodaje +1, do ostatniego numeru. Co oznacza że w pętli wszystko dzieje się za szybko i funkcja nie zdąży pobrać aktualnego numeru. Czy muszę spowolnić pętle o 1 sec na sprawdzaniu czy można zrobić to inaczej.
darko
Można zrobić to inaczej.
Randallmaster
Cytat(darko @ 16.12.2015, 00:30:19 ) *
Można zrobić to inaczej.


Takiej pomocy jak od ciebie jeszcze nigdy nie otrzymałem smile.gif Dzięki...
Pyton_000
Zadałeś pytanie, otrzymałeś bardzo konkretną odpowiedź.

To tak jak ostatnio z życia wzięte: "Przepraszam, chciałem kupić trochę części do auta. Muszę oddać mechanikowi czy można to inaczej zrobić?"
Randallmaster
  1. //w $data znajduje się lista dokumentów przykładowo 5 wierszy
  2. foreach($data as $r){
  3. $lastNr = getLastNumberDocument(); //w pętli wykonuje pobranie ostatniego numeru dokumentu zapisanego w poprzedniej pętli z $lastNr (zwraca int). funkcja wykona się 5 razy, więc powinno za pierwszym razem pobrać 0 (brak dokumentów), później 1, 2, 3, 4(czyli ostatnie zapisane numery z $lastNr). Na każdym poziomie pętli. Funkcja nie widzi tego co zostało zapisane w pętli poprzedniej ;/
  4.  
  5. //stworzenie następnego numeru dokumentu
  6. $lastNr += 1;
  7.  
  8. //zapis do bazy danych numeru $lastNr
  9. }


Idea jest taka że funkcja getLastNumberDocument() nie widzi tego co zapisuje do bazy danych w pętli czyli za każdym zwraca mi $lastNr = 1. I posiadam wtedy zdublowane dokumenty np. PZ/1, PZ/1, PZ/1, a powinno być PZ/1, PZ/2, PZ/3
Pyton_000
A gdzie masz zapisanie do BD?

PHP działa Liniowo (generalnie), więc w Twoim przypadku nie ma mozliwości o jakiej piszesz.

Jedyna możliwość to taka że nie zapisujesz do bazy, ot co.

No i pokaż kod getLastNumberDocument()
Randallmaster
  1. //w $data znajduje się lista dokumentów przykładowo 5 wierszy
  2. foreach($data as $r){
  3. $lastNr = getLastNumberDocument(); //w pętli wykonuje pobranie ostatniego numeru dokumentu zapisanego w poprzedniej pętli z $lastNr (zwraca int). funkcja wykona się 5 razy, więc powinno za pierwszym razem pobrać 0 (brak dokumentów), później 1, 2, 3, 4(czyli ostatnie zapisane numery z $lastNr). Na każdym poziomie pętli. Funkcja nie widzi tego co zostało zapisane w pętli poprzedniej ;/
  4.  
  5. //stworzenie następnego numeru dokumentu
  6. $lastNr += 1;
  7.  
  8. //zapis do bazy danych numeru $lastNr
  9. $this->SaveData($lastNr);
  10. }


Zapisuje do bazy. Przykładowo jeżeli będę wykonywał ręcznie pętle po 1 wierszu. Wtedy działa poprawnie. A jeżeli naraz w pętle wrzucę 5 pozycji to ma problem z odczytaniem tego co zapisałem w $this->SaveData
Pyton_000
Dalej nie pokazałeś kodów funkcji.
Ale strzelam że

nie:
Kod
$lastNr = getLastNumberDocument();


a:

Kod
$lastNr = $this->getLastNumberDocument();
Randallmaster
Cytat(Pyton_000 @ 16.12.2015, 09:01:48 ) *
No i pokaż kod getLastNumberDocument()


No funkcji mam trochę więcej i pokazanie całego kodu nie ma tu trochę sensu ponieważ działanie funkcji zwraca dane poprawnie, poza tym jeżeli po kolei wykonuje naraz w pętli 5 wierszy to nie widzi tego co w nich zapisywałem. Jeżeli na pętli dam opóźnienie o 1 sec to widzi. Chciałem tym kodem przybliżyć problem. Bo to nie chodzi o kod tylko samo działanie pętli i kolejność wykonywania

Może inaczej.

Jeżeli PHP działa liniowo to czy czeka na odpowiedź zapytania które wysyła do bazy danych, czy leci dalej w przypadku inserta? wygląda na to że puszcza zapis do bazy danych ale nie czeka aż zostanie potwierdzone zapisanie do bazy danych i wykonuje się dalej co skutkuje tym że pętla się wykona a on za każdym razem w funkcji getLastNumberDocument() widzi pustą zwrotkę.

Jest funkcja która zezwala na wykonanie następnej pętli jeżeli podana zmienna np. nie jest pusta?

Problem został rozwiązany. Wynikało to po stronie frameworka cakephp jeżeli widział on że zapytanie w ramach odświeżania było wykonywane to pobierał ten sam wynik.
NickOver
To o czym mówisz nazywa się "Race Condition". W skrócie, jeśli system pozwala wykonywać wiele operacji jednocześnie które są od siebie w pewien sposób zależne może zdarzyć się tak że coś się wykona szybciej mimo że zostało wywołane później. W Twoim przypadku najpierw leci insert a potem select, ale jeśli select pobierze dane szybciej niż insert je włoży to po prostu ich nie będzie (bo gdy były pobierane nie było ich). KLIK <- link do manuala mysql który trochę może pomóc.
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.