sqlite 데이터베이스로 작업하는 웹 응용 프로그램이 있습니다. 내 버전의 sqlite는 공식 Windows 바이너리 배포판 - 3.7.13의 최신판입니다.sqlite는 WAL 모드에서 SQLITE_BUSY를 반환합니다.
문제는 데이터베이스에 과부하가 걸리면 sqlite API 함수 (예 : sqlite3_step)가 SQLITE_BUSY를 반환한다는 것입니다. 연결을 초기화 할 때
나는 다음 pragma를 전달합니다
journal_mode = WAL
page_size = 4096
synchronous = FULL
foreign_keys = on
databas 한 파일 데이터베이스입니다. Mono 2.10.8 및 Mono.Data.Sqlite 어셈블리를 사용하여 데이터베이스에 액세스합니다.
각 응용 프로그램에 50 개의 후속 http 요청을 보내는 50 개의 병렬 스레드로 테스트하고 있습니다. 모든 요청에 대해 일부 읽기 및 쓰기가 데이터베이스에 수행됩니다. 모든 IO 작업 세트는 트랜잭션 내에서 실행됩니다.
400 번째 - 700 번째 요청까지 모든 것이 잘 진행됩니다. 이 (임의의) 순간에 API 함수는 SQLITE_BUSY를 영구적으로 반환하기 시작합니다 (정확히 말하면 다시 시도 한계에 도달 할 때까지).
내가 아는 한 WAL 모드는 병렬 읽기 및 쓰기를 투명하게 지원합니다. 체크 포인트 작업이 실행되는 동안 데이터베이스를 읽으려고 시도했기 때문일 수 있습니다. 그러나 자동 점검 점을 끈 후에도 상황은 동일하게 유지됩니다.
이 상황에서 잘못되었을 수있는 것은 무엇입니까? 대량의 병렬 데이터베이스 IO를 올바르게 제공하는 방법은 무엇입니까?
P.
요청 당 하나의 연결 만 가정합니다. WebSessionContext로 구성된 nhibernate를 사용합니다.
내가 이렇게 내 NHibernate에 세션을 초기화 :
ISession session = null;
//factory variable is session factory
if (CurrentSessionContext.HasBind(factory))
{
session = factory.GetCurrentSession();
if (session == null)
CurrentSessionContext.Unbind(factory);
}
if (session == null)
{
session = factory.OpenSession();
CurrentSessionContext.Bind(session);
}
return session;
그리고 HttpApplication.EndRequest을에
내가 이런 식으로 해제 ://factory variable is session factory
if (CurrentSessionContext.HasBind(factory))
{
try
{
CurrentSessionContext.Unbind(factory)
.Dispose();
}
catch (Exception ee)
{
Logr.Error("Error uninitializing session", ee);
}
}
를 지금까지 내가 아는 한 당 하나 개의 연결 만이 있어야한다 라이프 사이클을 요청하십시오. 요청을 처리하는 동안 코드는 순차적으로 실행됩니다 (ASP.NET MVC 3). 그래서 어떤 concurency도 여기에서 가능하지 않은 것처럼 보입니다. 이 경우 어떤 연결도 공유되지 않는다고 결론 내릴 수 있습니까?
는 별개의 연결은 각 요청에 대해 열, 아니면 모든 요청이 동일한 연결을 공유 할 수 있습니까? 또한 관련 코드 비트, 특히 스레드가 데이터베이스와 상호 작용하는 부분을 추가 할 수 있습니까? –
WAL 모드에 대한 가정이 잘못되었습니다. http://www.sqlite.org/wal.html에서 "WAL 파일이 하나뿐이므로 한 번에 하나의 작성자 만있을 수 있습니다." 쓰기로드가 많은 데이터베이스의 경우 PostgreSQL 또는 MySQL과 같은 것을 사용하십시오. –