I am using Execute method on the ADO command object to execute a stored procedure. This call throws an exception when the network adapter is disabled and re-enabled
why would the Execute fail in this case ?
The Execute fails because the underlying network connection has been lost (though the logical state of the Connection object will still appear as Open)
What you can do about this :
as a general rule, open your connection just before using it. Release it just after use,
have an error handling process which, on error, checks if the connection is closed, reopens it and rerun the Command.
I guess the answer depends on your use of your DB.
You could also imagine having a monitorig thread which performs simple select on a regular basis and reopens the connection if it is closed.
Related
I'm using QMYSQL to connect to a local database. The application runs over several threads. Each thread connects to database using an independent connection. Sometimes Qt throws following error when I try to connect to database. What's the problem?
QMYSQL: Unable to allocate a MYSQL object
Update
Added the code used to connect. This object is moved to a thread, the connection is named. critical is a signal emitted to main window to terminate application execution after a critical error (showing a message). log is a signal that is emitted to log incidences into database.
void ClientWorker::connect() {
m_database = QSqlDatabase::addDatabase("QMYSQL","wsc");
m_database.setHostName(m_host);
m_database.setDatabaseName(m_databaseName);
m_database.setPort(m_port);
m_database.setUserName(m_db_username);
m_database.setPassword(m_db_password);
if(!m_database.open()) {
QString error = "Unable to connect to database. Reason:\n";
error+= m_database.lastError().text();
log("Unable to connect to database! ", error, "ERROR" );
emit critical(tr("Database Error!"),error);
} else {
log("Connected to datbase successfully.", "", "NOTICE" );
}
Update 2
I just realized that every time a connection is made out of main thread, (with no active connections in main tread) the driver fails to load. I just added a small dummy connection code in main() that connects and disconnects immediately (before any thread connects). Adding that code, everything works fine. I'm not sure why threads can't connect before a connection in main thread, but I think it looks like a bug. Hope this helps someone, Took 3 days of mine :/
You might not care after your last update, but I have a theory based on it: this indicates mysql_library_init() has to be called from main() for multithreaded applications.
If you look in the Qt plugin source, that method is wrapped in qLibraryInit(), which is called from the QMYSQLDriver : QSqlDriver constructors, which in turn I believe get created indirectly by addDatabase() in your usage context.
The MySQL docs note that the mysql_library_init() can be done protected by a mutex, which would entail the QtSql code protecting all QSqlDriver construction, which I don't think it does. So I'm not sure if this would be considered a Qt code bug or a gap in documentation.
This all fits the behavior you've described, but I'm still doubtful of myself - if this is correct it surprises me that more people haven't run into this and it's not more evident on SO and other fora. I guess it's a little unusual to do your first DB activity on a spawned thread vs. at least some initial work in the main thread?
There is a bug related with QSqlDatabase::isOpen() in Qt.
http://bugreports.qt-project.org/browse/QTBUG-223
QSqlQuery::lastError() should give you an error if your query via QSqlQuery::exec() has failed. Also QSqlDatabase::isOpen() should report the state of your connection, QSqlDatabase::lastError() is also available
During testing of my project on a background server, I have encountered the weird situation where every time I triggers a request to my suspended server using ServerTestingTask, the ServerTask is triggered twice with identical SocketActivityTriggerDetails (trigger reason is SocketActivityTriggerReason::ConnectionAccepted, the socket information is always SocketActivityKind::StreamSocketListener). The problem is that the first one supplies a valid StreamSocket in the information and my code handled the request perfectly while the second trigger raises invalid object exception (just by accessing socketInformation->StreamSocket which is some kind of fatal and kill my server [need to resuming the app UI and click the button to start the server again]. It feels like the first trigger should indicate the socket kind to be SocketActivityKind::StreamSocket instead. Is it a known problem or is there some work around?
I make a standalone deubugger app using Microsoft's DbgEng.
I want to open a 2nd thread that sends commands to an additional IDebugControl instance, and I want to get the specific output for this IDebugControl Execute method call (and send it through a tcp connection).
I have a problem since the IDebugControl from main thread also sends commands to Execute() and the outputs might be mixed.
I need a second thread because once it execute a command like "g" (go) it will call WaitForEvent() and I won't be able to get any further information about the target until an event occurs.
I need a solution for that.
The second IDebugControl is used for operations that send requests for only data, like disassembly lines, memory dump...
I wonder if I can make a 2nd IDebugClient and attach it to the already opened debugged process, and then the problem is solved because I can put other callbacks to it.
Is there a solution for me?
I think you should not call any command to debug engine while it is waiting for events except IDebugControl::SetInterrupt.
If you want use two thread anyway you can register IDebugOutputCallbacks callback interface and handle output with any sort of mutex.
I have a problem with an sqlite3 db which remains locked/unaccessible after a certain access.
Behaviour occurs so far on Ubuntu 10.4 and on custom (OpenEmbedded) Linux.
The sqlite version is 3.7.7.1). Db is a local file.
One C++-applications accesses the db periodically (5s). Each time several insert statements are done wrapped in a deferred transaction. This happens in one thread only. The connection to the db is held over the whole lifetime of the application. The statements used are also persistent and reused via sqlite3_reset. sqlite_threadsafe is set to 1 (serialized), journaling is set to WAL.
Then I open in parellel the sqlite db with the sqlite command line tool. I enter BEGIN IMMEDIATE;, wait >5s, and commit with END;.
after this the db access of the application fails: the BEGIN TRANSACTION returns return code 1 ("SQL error or missing database"). If I execute an ROLLBACK TRANSACTION right before the begin, just to be sure there is not already an active transaction, it fails with return code 5 ("The database file is locked").
Has anyone an idea how to approach this problem or has an idea what may cause it?
EDIT: There is a workaround: If the described error occures, I close and reopen the db connection. This fixes the problem, but I'm currently at a loss at to why this is so.
Sqlite is a server less database. As far as I know it does not support concurrent access from multiple source by design. You are trying to access the same backing file from both your application and the command tool - so you attempt to perform concurrent access. This is why it is failing.
SQLite connections should only be used from a single thread, as among other things they contain mutexes that are used to ensure correct concurrent access. (Be aware that SQLite also only ever supports a single updating thread at once anyway, and with no concurrent reads at the time; that's a limitation of being a server-less DB.)
Luckily, SQLite connections are relatively cheap when they're not doing anything and the cost of things like cached prepared statements is actually fairly small; open up as many as you need.
[EDIT]:
Moreover, this would explain closing and reopening the connection works: it builds the connection in the new thread (and finalizes all the locks etc. in the old one).
i know little about pipes but have used one to connect two processes in my code in visual C++. The pipe is working well, but I need to add error handling to the same, hence wanted to know what will happen to a pipe if the server creating it crashed and how do I recognize it from client process?
Also what will happen if the client process tried accessing the same pipe, after the server crash, if no error handling is put in place?
Edit:
What impact will be there on the memory if i keep creating new pipes (say by using system time as pipe name) while the previous was broken because of a server crash? Will these broken pipes be removed from the memory?
IIRC the ReadFile or WriteFile function will return FALSE and GetLastError() will return STATUS_PIPE_DISCONNECTED
I guess this kind of handling is implemented in your code, if not you should better add it ;-)
I just want to throw this out there.
If you want a survivable method for transferring data between two applications, you might consider using MSMQ or even bringing in BizTalk or another message platform.
There are several things to consider:
what happens if the server is rebooted or loses power?
What happens if the server application becomes unresponsive?
What happens if the server application is killed or goes away completely?
What is the appropriate response of a client application in each of the above?
Each of those contexts represent a potential loss of data. If the data loss is unacceptable then named pipes is not the mechanism you should be using. Instead you need to persist the messages somehow.
MSMQ, storing to a database, or even leveraging Biztalk can take care of the survivability of the message itself.
If 1 or 3 happens, then the named pipe goes away and must be recreated by a new instance of your server application. If #2 happens, then the pipe won't go away until someone either reboots the server or kills the server app and starts it again.
Regardless, the client application needs to handle the above issues. They boil down to connection failed problems. Depending on what the client does you might have it move into a wait state and let it ping the server every so often to see if it has come back again.
Without knowing the nature of the data and communication processes involved its hard to recommend a proper approach.