ÎÊÌâÃèÊö
ÎÒµÄ python/wsgi Web Ó¦ÓóÌÐòÖеĻỰÓÐÎÊÌâ.2 ¸ö wsgi ÊØ»¤½ø³ÌÖеÄÿ¸öÏ̶߳¼ÓÐÒ»¸ö²»Í¬µÄ¡¢³Ö¾ÃµÄ mysqldb Á¬½Ó.ÓÐʱ£¬ÔÚɾ³ý¾É»á»°²¢´´½¨Ð»Ựºó£¬Ä³Ð©Á¬½ÓÈÔÈ»ÔÚÑ¡ÔñÖлñÈ¡¾É»á»°£¬ÕâÒâζ×ÅËüÃÇÎÞ·¨ÑéÖ¤»á»°²¢ÔÙ´ÎÒªÇóµÇ¼.
I'm having a problem with the sessions in my python/wsgi web app. There is a different, persistent mysqldb connection for each thread in each of 2 wsgi daemon processes. Sometimes, after deleting old sessions and creating a new one, some connections still fetch the old sessions in a select, which means they fail to validate the session and ask for login again.
ÏêϸÐÅÏ¢:»á»°´æ´¢ÔÚ±¾µØ mysql Êý¾Ý¿âµÄ InnoDB ±íÖÐ.Éí·ÝÑéÖ¤ºó(ͨ¹ý CAS)£¬ÎÒɾ³ý¸ÃÓû§Ö®Ç°µÄËùÓлỰ£¬´´½¨Ò»¸öлỰ(²åÈëÒ»ÐÐ)£¬Ìá½»ÊÂÎñ£¬²¢Ê¹Óà cookie ÖеÄлỰ ID Öض¨Ïòµ½×î³õÇëÇóµÄÒ³Ãæ.¶ÔÓÚÿ¸öÇëÇ󣬶¼»á¸ù¾ÝÊý¾Ý¿âÖеĻỰ¼ì²é cookie ÖеĻỰ ID.
Details: Sessions are stored in an InnoDB table in a local mysql database. After authentication (through CAS), I delete any previous sessions for that user, create a new session (insert a row), commit the transaction, and redirect to the originally requested page with the new session id in the cookie. For each request, a session id in the cookie is checked against the sessions in the database.
ÓÐʱ£¬Öض¨ÏòºóÔÚÊý¾Ý¿âÖÐÕÒ²»µ½Ð´´½¨µÄ»á»°.Ïà·´£¬¸ÃÓû§µÄ old »á»°ÈÔÈ»´æÔÚ.(ÎÒͨ¹ýÔÚÿ¸öÇëÇó¿ªÊ¼Ê±Ñ¡Ôñ²¢¼Ç¼ËùÓлỰÀ´¼ì²éÕâÒ»µã).²»ÖªºÎ¹Ê£¬Îҵõ½ÁË»º´æµÄ½á¹û.ÎÒ³¢ÊÔʹÓà SQL_NO_CACHE Ñ¡Ôñ»á»°£¬µ«Ã»ÓÐÈκÎÇø±ð.
Sometimes, a newly created session is not found in the database after the redirect. Instead, the old session for that user is still there. (I checked this by selecting and logging all of the sessions at the beginning of each request). Somehow, I'm getting cached results. I tried selecting the sessions with SQL_NO_CACHE, but it made no difference.
ΪʲôÎÒ»áµÃµ½»º´æµÄ½á¹û?»º´æ»¹ÄÜÔÚÄÄÀï·¢Éú£¬ÈçºÎÍ£Ö¹»òˢлº´æ?»ù±¾ÉÏ£¬ÎªÊ²Ã´ÆäËûÁ¬½Ó¿´²»µ½Ð²åÈëµÄÊý¾Ý?
Why am I getting cached results? Where else could the caching occur, and how can stop it or refresh the cache? Basically, why do the other connections fail to see the newly inserted data?
ÍƼö´ð°¸
MySQL ĬÈϸôÀ뼶±ðΪREPEATABLE READ"£¬ÕâÒâζ×ÅÔÚÊÂÎñ¿ªÊ¼ºóÄú½«¿´²»µ½ÊÂÎñÖеÄÈκθü¸Ä - ¼´Ê¹ÄÇЩ(ÆäËû)ÒÑÌá½»¸ü¸Ä.
MySQL defaults to the isolation level "REPEATABLE READ" which means you will not see any changes in your transaction that were done after the transaction started - even if those (other) changes were committed.
Èç¹ûÄúÔÚÕâЩ»á»°Öз¢³ö COMMIT »ò ROLLBACK£¬ÄúÓ¦¸Ã»á¿´µ½¸ü¸ÄµÄÊý¾Ý(ÒòΪÕ⽫½áÊøÕýÔÚ½øÐÐ"µÄÊÂÎñ).
If you issue a COMMIT or ROLLBACK in those sessions, you should see the changed data (because that will end the transaction that is "in progress").
ÁíÒ»¸öÑ¡ÏîÊǽ«ÕâЩ»á»°µÄ¸ôÀ뼶±ð¸ü¸ÄΪREAD COMMITTED".Ò²Ðí»¹ÓÐÒ»¸öÑ¡Ïî¿ÉÒÔ¸ü¸ÄĬÈϼ¶±ð£¬µ«ÄúÐèÒª²é¿´ÊÖ²á.
The other option is to change the isolation level for those sessions to "READ COMMITTED". Maybe there is an option to change the default level as well, but you would need to check the manual for that.
Õâƪ¹ØÓÚΪʲôһЩmysqlÁ¬½ÓÔÚɾ³ý+²åÈëºóÑ¡ÔñmysqlÊý¾Ý¿âÖеľÉÊý¾Ý?µÄÎÄÕ¾ͽéÉܵ½ÕâÁË£¬Ï£ÍûÎÒÃÇÍƼöµÄ´ð°¸¶Ô´ó¼ÒÓÐËù°ïÖú£¬Ò²Ï£Íû´ó¼Ò¶à¶àÖ§³Ö¸ú°æÍø£¡