Python/wsgi 웹 애플리케이션의 세션에 문제가 있습니다. 2개의 wsgi 데몬의 각 스레드는 서로 다른 지속적인 mysqldb 연결을 가지고 있습니다. 때로는 이전 세션을 삭제하고 새 세션을 생성한 후에도 일부 연결에서 여전히 이전 세션을 선택하게 됩니다. 즉, 세션을 인증하지 못하고 다시 로그인하도록 요청하는 것입니다.
세부 정보: 세션은 로컬 mysql 데이터베이스의 InnoDB 테이블에 저장됩니다. CAS를 통해 인증한 후 해당 사용자의 이전 세션을 삭제하고 새 세션을 생성(행 삽입)한 다음 트랜잭션을 커밋하고 쿠키의 새 세션 ID를 사용하여 원래 요청한 페이지로 리디렉션합니다. 각 요청에 대해 쿠키의 세션 ID를 데이터베이스의 세션과 비교하여 확인합니다.
새로 생성된 세션이 리디렉션 후 데이터베이스에서 발견되지 않는 경우가 있습니다. 대신 사용자의 old 세션이 여전히 존재합니다. (각 요청 시작 시 모든 세션을 선택하고 기록하여 이를 확인했습니다.) 어떻게 든 캐시된 결과를 얻습니다. 세션을 선택하기 위해 SQL_NO_CACHE를 사용해 보았지만 아무런 차이가 없었습니다.
캐시된 결과를 얻는 이유는 무엇인가요? 캐싱이 발생할 수 있는 다른 곳은 어디이며 캐싱을 중지하거나 캐시를 플러시하려면 어떻게 해야 합니까? 기본적으로 왜 다른 연결에서는 새로 삽입된 데이터를 볼 수 없습니까?
예, 한 번의 거래만 수행한 다음 연결을 끊는다고 가정한 것 같습니다. 요구 사항이 다른 경우에는 이 가정을 해결해야 합니다. @a_horse_with_no_name이 언급했듯이 커밋할 수 있습니다(실제로 데이터를 변경하지 않은 경우 롤백을 사용하지만). 또는 커서의 격리 수준을 변경할 수 있습니다. 이 토론에서 다음을 사용했습니다.
dbcursor.execute("设置会话事务隔离级别读取已提交")
또는 연결에서 자동 커밋을 true로 설정할 수 있는 것 같습니다.
dbconn.autocommit(True)
그러나 실제로 연결을 변경하는 경우에는 권장되지 않습니다.
MySQL 기본 격리 수준 "REPEATABLE READ"는 트랜잭션이 시작된 후에는 변경 사항이 표시되지 않음을 의미합니다. 이러한 (다른) 변경 사항이 커밋된 경우에도 마찬가지입니다.
이 세션에서 COMMIT 또는 ROLLBACK을 실행하면 변경된 데이터가 표시됩니다(이렇게 하면 "진행 중인" 트랜잭션이 종료되므로).
또 다른 옵션은 이러한 세션의 격리 수준을 "READ COMMITTED"로 변경하는 것입니다. 기본 수준을 변경하는 옵션도 있을 수 있지만 설명서를 확인해야 합니다.