Handling concurrent access lazarus / 16-Databases ---------------------------------------------------------------------- Leledumbo · 2010-12-30 15:17 I'm currently writing a web service with data upload and retrieval. As a web service, it will surely be used concurrently. All provided services do database access. The problem is when the data size is quite large (when uploading big files for instance), another incoming request causes internal server error. If not big, two request incoming in almost the same time could cause that too (tried from extjs). How do I solve this? ---------------------------------------------------------------------- typo · 2010-12-30 17:02 Probably you need a Mutex, http://en.wikipedia.org/wiki/Mutual_exclusion For instance, this code avoids this program to be executed twice: Code: [Select]program project1; {$mode objfpc}{$H+} uses   {$IFDEF UNIX}{$IFDEF UseCThreads}   cthreads,   {$ENDIF}{$ENDIF}   Interfaces, // this includes the LCL widgetset   Forms, Unit1   { you can add units after this }   ,windows; {$R *.res} var   hMutex: THandle; begin   hMutex := Crea]"]>Blockedtex(nil, True, PChar('MyUniqueName'));   if (hMutex <> 0) and (GetLastError = 0) then   begin     Application.Initialize;     Application.CreateForm(TForm1, Form1);     Application.Run;   end; end. ---------------------------------------------------------------------- Leledumbo · 2010-12-31 04:39 Well, what should I say to the currently waiting request then? Reject with "database is busy" or what? I wonder how PHP handles this. ---------------------------------------------------------------------- typo · 2010-12-31 10:07 You could wait on a loop until a timeout and use a message like "Timeout reached ". Someting like: Code: [Select]  TimeOut := GetTickCount + 10000;   repeat     hMutex := Crea]"]>Blockedtex(nil, True, PChar('MyUniqueName2'));     Application.ProcessMessages;   until ((hMutex <> 0) and (GetLastError = 0)) or (GetTickCount > TimeOut);   if (hMutex <> 0) and (GetLastError = 0) then   begin     try        //       // your code       //     finally       ReleaseMutex(hMutex);     end;   end   else     ShowMessage('Timeout reached'); ---------------------------------------------------------------------- Leledumbo · 2010-12-31 10:48 Thanks, but without asking, I know that it's Windows only. The deployment platform is a Linux box. Perhaps I need a critical section? ---------------------------------------------------------------------- typo · 2010-12-31 11:15 I don't know if there is any implementation of Mutexes for Linux in Lazarus. AFAIK, Linux Mutexes can't be used to different processes, maybe you need a Semaphore, more specifically a Binary Semaphore. ---------------------------------------------------------------------- McCorder · 2011-01-03 17:53 Probably a silly comment, but for web services shouldn't you pass off each request onto a separate thread allowing more than one to run concurrently ? You could limit the numbers of threads by having a pool of available ones for use. ---------------------------------------------------------------------- typo · 2011-01-03 18:05 Mutexes allow different threads or processes to share resources that should be accessed by one at a time. ---------------------------------------------------------------------- Leledumbo · 2011-01-04 14:36 QuoteProbably a silly comment, but for web services shouldn't you pass off each request onto a separate thread allowing more than one to run concurrently ? You could limit the numbers of threads by having a pool of available ones for use.With one database server, that wouldn't make any difference. Either mutex or semaphore, I don't really care. It's just something that can block for a while when another operation is using the database. Update: I've got an idea to use empty temp file to indicate whether a process is using the database or not and wait until that file gets deleted. ---------------------------------------------------------------------- typo · 2011-01-04 14:48 Except for the fact that file creation and deletion can have their own errors, mutexes or binary semaphores have the same effect. ---------------------------------------------------------------------- McCorder · 2011-01-08 23:47 Quote from: Leledumbo on January 04, 2011, 03:36:45 pmQuoteProbably a silly comment, but for web services shouldn't you pass off each request onto a separate thread allowing more than one to run concurrently ? You could limit the numbers of threads by having a pool of available ones for use.With one database server, that wouldn't make any difference. Either mutex or semaphore, I don't really care. It's just something that can block for a while when another operation is using the database. Update: I've got an idea to use empty temp file to indicate whether a process is using the database or not and wait until that file gets deleted. The database server (if it is a server) will be able to handle multiple connections. So you have a pool of them (say 10) which you pass off to a new thread in response to a new request. If you need to block then your server is not a server really, it can only handle one request. ---------------------------------------------------------------------- Leledumbo · 2011-01-09 02:58 QuoteThe database server (if it is a server) will be able to handle multiple connections. So you have a pool of them (say 10) which you pass off to a new thread in response to a new request. If you need to block then your server is not a server really, it can only handle one request.Yeah, probably the client library isn't compiled with thread safe option enabled.