Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 8 of 8 total
Thread *** URGENT *** ElevateDB Error #506 Cannot lock the session manager (ID: 1)
Tue, Feb 21 2012 7:37 AMPermanent Link

Hedley Muscroft

(Visual Studio 2010 C# - EDB 2.7 build 1)

My application has an abstracted "data layer" which allows me to switch backends. It's been running for a couple of years with EDB (File-based) and PostgreSQL. I've just added in another implementation of the data layer for EDB "Client/Server" and as a result, I'm now getting the following error occur A LOT :-

"ElevateDB Error #506 Cannot lock the session manager (ID: 1)"

I've searched the forums and found Tim's four possible explanations here :-
http://www.elevatesoft.com/forums?action=view&category=edb&id=edb_sql&page=1&msg=4744&start=1&keywords=506&searchbody=True

I think my problem is related to the following :-
>> It is possible to get a #506 error solely on the client side with a remote
>> session if you try to do something with a session while it's in the middle
>> of waiting on a response from the EDB Server.  In Dale's case it was a timer
>> event getting fired due to the message loop being processed, and an attempt
>> to request something from the server using the same remote session in the
>> timer event.

...because the problem only seems to occur when DB code is executed from a TIMER event, and occasionally from an asynchronous thread (although that doesn't happen much).

I hasten to add that my application IS thread-safe and runs perfectly with PostgreSQL and the File-Based EDB data-layer.

In the EDB C/S data layer, I have used critical sections to make ensure it's completely thread-safe, by wrapping every database call with a "lock" statement (see http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx) however this has not solved the problem, and I'm still seeing this excepetion repeatedly - especially when background timer events fire to refresh various screens.

Any suggestions please?

PS: Sorry to be a pain, but this is quite urgent as a I rolled out a new release to customers before realising this problem existed - thanks!
Tue, Feb 21 2012 8:11 AMPermanent Link

Hedley Muscroft

As a follow-up question, the recommendation to fix this problem has been :-

>> use the .TryLock method to see if you are able to lock the session
>>  if TEDBEngineSessionManager(EDBSession1.Handle).TryLock(1, 0) then begin      
>>    TEDBEngineSessionManager(EDBSession.Handle).Unlock;                                    
>>    {Session is not locked and is safe for you to use}
>>  end else begin
>>    {Session is currently locked, better wait a bit and try again.}
>>  end;

How do I do this via the .NET provider?
Fri, Feb 24 2012 8:12 AMPermanent Link

inzKulozik

There is a one basic rule with threads - every thread should have own separate session.

Hedley Muscroft wrote:

In the EDB C/S data layer, I have used critical sections to make ensure it's completely thread-safe, by wrapping every database call with a "lock" statement
Wed, Feb 29 2012 4:07 AMPermanent Link

Hedley Muscroft

>> There is a one basic rule with threads - every thread
>> should have own separate session.

Thanks for the suggestion. There is no "Session" object in the .NET components. The only thing that you could do is create a new EDBConnection object for each separate thread.

I have just managed to fix the problem myself. The cause of the issue was that I was passing an EDBDataAdapter to a "data-agnostic" DLL which accepts any DbDataAdapter descendant and calls .Fill(...)" from within a Timer.Tick(...) event.

I made some modifications in order to use a callback to the EDB-specific data-layer instead, which uses the lock(...) convention to ensure thread-safety.

Tim: is this something that perhaps needs to be made more clear in the .NET documentation?
Wed, Feb 29 2012 2:08 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Hedley,

<< How do I do this via the .NET provider? >>

I wouldn’t recommend doing that, frankly.  It relies on internal calls, and
I usually don't recommend using any internal calls.

--
Tim Young
Elevate Software
www.elevatesoft.com
Wed, Feb 29 2012 2:09 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Hedley,

<< Tim: is this something that perhaps needs to be made more clear in the
..NET documentation? >>

Under the EDBConnection class, there's this:

"The EDBConnection class implements the DbConnection abstract class,
providing an encapsulation of an ElevateDB local or remote session connected
to a given ElevateDB database. A session acts like a "virtual user" and each
new EDBConnection instance used in an application maintains its own database
connections, table buffers, table/view/query result set cursors, etc.
Because of the unique requirements of a multi-threaded application,
ElevateDB requires that you use a separate EDBConnection component for each
thread in use, thus treating each thread as a separate "virtual user"."

--
Tim Young
Elevate Software
www.elevatesoft.com


Fri, Mar 2 2012 5:00 AMPermanent Link

Hedley Muscroft

>> Because of the unique requirements of a multi-threaded application,
>> ElevateDB requires that you use a separate EDBConnection component for each
>> thread in use

My bad - I didn't spot that. Thanks Tim.

Something does confuse me though - does a Timer.Tick() event actually occur in a separate thread? My understanding was that the Timer itself ran in separate thread, but the Tick event was some sort of clever call-back to the main UI thread.

For example, you can't manipulate visual components from a method running in a different thread, without first checking ".InvokeRequired" and then manipulating the components via the .Invoke() convention. However that is never necessary from a Tick event... hence my presumption that Tick() occurs in the main thread.

Can you shed any light on this?! Thanks!
Mon, Mar 5 2012 11:59 AMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Hedly,

<< Something does confuse me though - does a Timer.Tick() event actually
occur in a separate thread? My understanding was that the Timer itself ran
in separate thread, but the Tick event was some sort of clever call-back to
the main UI thread. >>

This link is very helpful in outlining the various Timer classes in .Net and
how they are implemented:

http://msdn.microsoft.com/en-us/magazine/cc164015.aspx

In general, Windows timers (System.Windows.Forms.Timer) are processed via
the main UI thread's message loop, so they are never re-entrant.  You can
still run into issues if you force the processing of messages while EDB is
in the middle of executing something (OnProgress event handler, for
example).  In such cases, any database activity in the timer event handler
could possibly cause a problem or weird errors if you try to use the same
EDBCommand instance that is already in use executing an SQL statement that
triggered the OnProgress event.

--
Tim Young
Elevate Software
www.elevatesoft.com
Image