From: Claudio V. C. <cv...@us...> - 2003-03-08 07:22:50
|
Valdir Stiebe Junior wrote: > Subject: Re: [Firebird-devel] Changing maximum items IN clause > > > I dunno if this have anything related to the thread, but sometimes on > procedures with the statement for select .... where MYFIELD in ( > select ... ) do i got the error "Too many concurrent executions of > the same request". Don't matter if the procedure is recursive or not. > This is a limit? Yes, this is a limit. Deep inside the engine, for some low level operations, the request is "cloned". I think that if this happens too many times, you will get that message. If you are curious, here's your error msg at compile time, slightly different and only for metadata changes: jrd/cmp.cpp: // Find an inactive incarnation of a system request. // If necessary, clone it. JRD_REQ DLL_EXPORT CMP_find_request(TDBB tdbb, USHORT id, USHORT which) { ... for (n = 1;; n++) { if (n > MAX_RECURSION) { THD_MUTEX_UNLOCK(dbb->dbb_mutexes + DBB_MUTX_cmp_clone); ERR_post(gds_no_meta_update, gds_arg_gds, gds_req_depth_exceeded, gds_arg_number, (SLONG) MAX_RECURSION, 0); /* Msg363 "request depth exceeded. (Recursive definition?)" */ } clone = CMP_clone_request(tdbb, request, n, FALSE); if (!(clone->req_flags & (req_active | req_reserved))) { clone->req_flags |= req_reserved; THD_MUTEX_UNLOCK(dbb->dbb_mutexes + DBB_MUTX_cmp_clone); return clone; } } And here's your message at execution time for typical data changes, exactly as you see it: jrd/exe.cpp: // Find an inactive incarnation of a trigger request. // If necessary, clone it. JRD_REQ EXE_find_request(TDBB tdbb, JRD_REQ request, BOOLEAN validate) { ... clones = (vector = request->req_sub_requests) ? (vector->count() - 1) : 0; for (n = 1; n <= clones; n++) { next = CMP_clone_request(tdbb, request, n, validate); if (next->req_attachment == tdbb->tdbb_attachment) { if (!(next->req_flags & req_in_use)) { clone = next; break; } else count++; } else if (!(next->req_flags & req_in_use) && !clone) clone = next; } if (count > MAX_CLONES) { THD_MUTEX_UNLOCK(dbb->dbb_mutexes + DBB_MUTX_clone); ERR_post(gds_req_max_clones_exceeded, 0); } Basically, this may be caused by code that forces a trigger to run, then the trigger invokes operations that cause (may be indirectly) that trigger to fire up again, so the trigger is calling itself many times. A silly example would be a before insert trigger that inserts itself another record in the same table where it's defined. A subtle example of a trigger on table A that changes table B, but table B has a trigger that's invoked by such change and in turn modifies table A, causing the first trigger to run. In both cases, the trigger has not finished yet when it's invoked in the context of the same top level request, so it's a recursive call. (I mean you shouldn't have trouble if 100 insertions from different clients cause the same trigger to fire, because it's happening in different requests). A typical SQL statement is a request. A request has to be compiled to be executed, unless you're using the "execute immediate" API call. Some statements, like "CREATE DATABASE", can't be prepared at all. C. |