CDbHttpSession i CController redirect()

Witam,

mam problem z CDbHttpSession . Dane sesji nie zawsze są zapisywane do bazy jeśli wywołuję redirect() lub refresh().

Muszę bezpośrednio wywołać


Yii::app()->session->close();

przed redirect() lub refresh().

Nawet


Yii::app()->onEndRequest = array(Yii::app()->session, 'close');

nie pomaga.

Czy ktoś zna ten problem? Jeśli używam sesji opartej na plikach, wszystko działa poprawnie.

Tyle znalazłem:

http://code.google.com/p/yii/issues/detail?id=2406

Problem chyba taki sam.

Nadpisałem redirect() w Controller i jest dobrze:


    

public function redirect($url, $terminate=true, $statusCode=302)

{

    if (Yii::app()->session->useCustomStorage) {

        Yii::app()->session->close();

    }

    parent::redirect($url, $terminate, $statusCode);

}



Tylko nie rozumiem dlaczego to nie zadziałało:


Yii::app()->onEndRequest = array(Yii::app()->session, 'close');

używasz "useCustomStorage", wiec zakladam, ze trzymasz sesje w bazie lub innym keszu zamiast standardowych plikow. problom moze polegac na tym, ze o ile standardowe pliki sa blokowane na czas procesowania skryptu (pomiedzy session::open i session::close), to inne mechanizmy czesto tego nie maja (np. odczyt z bazy to select, zapis - update, ale pomiedzy select a update inne procesy php moga sie odwolywac do rekordu sesji, nie jest on zablokowany). jesli teraz jeden proces php wygeneruje redirect (header Location) to przegladarka moze odwolac sie do tego adresu zanim jeszcze obsluga poprzedniego requestu sie zakonczy w skrypcie php. serwer www obsluzy ten kolejny request za pomoca nowego procesu php, ktory pobierze dane sesji zanim jeszcze poprzedni proces je zapisze. W przypadku obslugi sesji za pomoca plikow ten drugi request zawisl by do czasu zwolnienia blokady na pliku, czyli do czasu az pierwszy proces wykonalby session::close na koncu swojej pracy. dlatego tez reczne wywolanie session::close przed redirectem (co powoduje zapisanie danych sesji) rozwiazuje problem…

zagadnienie blokady zasobow w przypadku sesji to dosc znany problem - z jednej strony uniemozliwia rownolegle procesowanie requestow od tego samego uzytkownika (co jednak zwykle nie jest potrzebne) przy tym rozwiazuje problem wielodostepu do sesji, z drugiej - jest mniej wydajne (nie ma wielodostepu, mechanizm flock do najszybszych nie nalezy, itp…)