i have an out of process COM server written with the help of ATL. Under normal circumstances the lifetime of that server is conveniently handled for you however if a client process dies prior to releasing its interface the server seems to linger around forever.
Is there a way (or a timeout that i don't know about) that allows the server to enter its shutdown procedure when no clients are connected. Or i guess another way to put it is how does ATL/COM handle the ref count for clients that crash?
There is a timeout to dereference stubs in your COM server in a few minutes, so it should not take forever. However, another problem you might be having is that as a part of operation COM objects in your server have cross references which are not properly released with this sudden death of connected client. In this case, your COM object will keep locks on the server process and prevent it from auto-termination which you expect to happen.
Related
In Go, when using a SQL database, does one need to close the DB (db.Close) before closing an application? Will the DB automatically detect that the connection has died?
DB will do its best to detect but with no luck, it may not be able to detect. Better to release what is acquired as soon as possible.
send() system call will wait for TCP connection to send data but client won't receive anything.
Power failure, network issue or bare exit happened without properly releasing resources. TCP keepalive mechanism will kick in and try to detect that connection is dead.
Client is paused and doesn't receive any data, in this case send() will block.
As a result, it may prevent
Graceful shutdown of cluster.
Advancing event horizon if it was holding exclusive locks as a part of transaction such as auto vacuum in postgresql.
Server keepalive config could be shortened to detect it earlier. (For example, ~2h 12m default in postgresql will be very long according to workload).
There may be a hard limit on max open connections, until detection, some connections will be zombie (there, unusable but decreases limit).
The database will notice the connection had died and take appropriate actions: for instance, all uncommitted transactions active on that connection will be rolled back and the user session will be terminated.
But notice that this is a "recovery" scenario from the point of view of the database engine: it cannot just throw up when a client disconnects; it rather have to take explicit actions to have consistent state.
On the other hand, to shut down property when the program goes down "the normal way" (that is, not because of a panic or log.Fatal()) is really not that hard. And since the sql.DB instance is usually a program-wide global variable, its even simpler: just try closing it in main() like Matt suggested.
If you're initialising a connection in any function, you're normally better off deferring the call to close immediately, i.e.
conn := sql.Connect() // for example
defer conn.Close()
Which will close the connection once the enclosing function exits.
This is handy when used in a main function since once the program exits, the call to Close() will happen.
I am developing an application that calls a web service, which deletes information from a database (the web service was developed by a third party vendor). On the first run approximately 100,000 records are deleted.
I have tested the routine a few times and this appears in Visual Studio occasionally:
"The CLR has been unable to transition from COM context 0x22c4f60 to COM context 0x22c51b0 for 60 seconds.
The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages.
This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time.
To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations."
I assume that the web service is taking more than sixty seconds to pass control back to the .NET Forms app. Please see the following quote from the message: "To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations". As this is a Windows Forms app, does this mean that I do not need to do anything to allow for this?
Sometimes this issue may also occur due to wrong server name, like if you had included SERVER/SQLEXPRESS instead of SERVER\SQLEXPRESS then also this error displays, which was my case.
Check and be sure if you are using a reader that you do not included try/catches. You should make and effort to try and resolve your solution issue better than that. A try/catch will cause a time out especially in a while loop.
A long-running application uses the MS C OBDC API to create and use SQL connections to an Oracle DB. The application was originally designed to establish an ODBC connection at startup and keep that connection indefinitely as the application runs, potentially for weeks or months.
We're seeing very infrequent cases where a connection suddenly dies and I wondered if that's because we're using them wrong, or if it's considered OK to hold a connection like this. Can anyone point me to some definitive information on the subject?
I'm not sure there's definitive information regarding this, but with long-running programs you always have to be prepared for this kind of incidents, they just happen (and not only with db connections but also with sockets that remain open for extended periods). I have no experience with Oracle, but I have a very similar setup with Informix, and this is (in pseudocode) what we do
while (programissupposedtorun) {
opendb();
do {
youractivities();
} while(dbisok);
closedbandcleanup();
}
As long as you are able to correctly detect that the connection died and are able to resume processing without losing data you should be OK.
I'm not familiar with ODBC but such use cases are best handled with a connection pool. Your application can simply request a connection from the pool when it has some work and release it as soon as its done -- the pool will take care of actually (re)connecting to the database.
A quick search for ODBC connection pooling brought this up: Driver Manager Connection Pooling
I'm using SQL Compact 3.5 SP2. My application is multi-threaded, but it does not share connections across threads. Instead, I use a custom object pool to ensure that each thread gets its own connection. That said, it's possible that a connection might be re-used on different threads at different times... in other words, I'm assuming that the connections don't have thread affinity. Also, not sure if it matters, but I'm using Entity Framework in .NET 3.5 SP1.
Anyway, when I've got high load situations (8+ threads), I'm getting lock timeout exceptions (regardless of the length of the timeout setting), and the exception always says the lock was on the __SysObjects table.
I'm not doing any DDL, so I don't understand why I would get locking timeouts on that table. Ideas?
I somewhat resolved this issue by making sure that my connections were closed after each use (as opposed to pooling the open connections), but if I let the code run for a long period of time I started getting OutOfMemoryException and AccessViolation exceptions.
This smells like the SqlCeConnection class has some kind of thread affinity dependency. Either that, or it has a memory leak of some kind.
At any rate, I've given up on trying to pool these objects.
EDIT: This actually appears to be an issued address by Cummulative Update 2. Since updating my references to the new libs, I haven't seen this problem. See: http://support.microsoft.com/kb/983516
I've had this problem before and found that basically I've got a connection that I'm not closing quickly enough (leaving connections open and waiting for garbage collection isn't really a best practice).
Now I'm getting it again but I can't seem to find where I'm leaving my connections open. By the time is see the error the database has cleared out the old connections so I can't see all the locked up connections last command (very helpful last time I had this issue).
Any idea how I could instrument my code or database to track what's going on so I can find my offending piece of code?
The error you are providing doesnt really point to a connection that is left open; it is more likely that there is a query that is taking longer than the application expects.
you can increase the time it waits for a response, and you could use Sql to find which queries are the most taxing.
Hopefully you have one data access layer class, instead of a whole bunch of classes, each one creating its own connection, right? What language are you using? If your using C#, the biggest cause of this problem is DataReaders and returning these objects to the upper layers. Most likely some client class is not closing the DataReader it received from your DAL class, leaving the connection open/locked for who knows how long. Track down the DataReaders you're returning and make sure your client classes are closing/disposing of them properly.
I'd also start thinking about redesigning your data access layer by implementing Disposable pattern and possibly returning POCOs instead of Data (...Tables, ...Sets, ...Readers) objects.