[Qt-interest] Postgresql-8.3 blocking with qt 3.3.3 - SOLVED

John A. Sullivan III jsullivan at opensourcedevel.com
Sat Dec 27 21:00:23 CET 2008


On Fri, 2008-12-26 at 20:49 -0500, John A. Sullivan III wrote:
> Hello, all.  I'm having a bizarre problem with postgresql-8.3 and qt
> 3.3.3 on Ubuntu 8.0.4 fully patched.  That's my troubleshooting
> environment but we originally saw this problem on RHEL 5.2.  We are
> using the QPSQL7 driver.  The database has a public schema for shared
> production use and each administrator creates a copy of the public
> schema for edits and then merges those edits into production at the end
> of their session.  This is for the open source network security
> management project ISCS (http://iscs.sourceforge.net).
> 
> During the update of the security gateways, we spawn several threads to
> apply the updates.  When the thread terminates, it creates a custom
> event in the main event loop.  The event handler reads the database
> version from the thread and updates the public (production) schema with
> the value.  The update is made using a QSqlQuery object with very simple
> SQL.  The actual query does not seem to matter.  As soon as this query
> executes, the public schema seems to block.  It query returns true, the
> code logic progresses, but the change has not been made (it is a single
> change not bounded by a transaction) and any subsequent action upon the
> public schema fails.  Actions upon the edit schema appear to work fine.
> Previous updates using the same object work perfectly fine.  Only this
> one fails.  The only unique characteristic is it is called within the
> custom event handler upon thread termination. The threads open their own
> QSqlDatabase and QSqlQuery objects.
> 
> I've tracked it down to this specific query by running an independent
> instance of psql from a terminal.  As I step through the code, line by
> line, I begin a transaction, do a simple update to the public schema and
> then rollback the transaction.  It works fine up until I execute the
> QSqlQuery.  The query in the code is very simple:
> 
> update peps set dbversion=6, current=true where pep='WessonSGGW';
> 
> I can run it within a transaction in psql by simply cutting and pasting
> from the debugger.  I even coded an even simpler update in its place:
> 
> "update peps set comment='fudge' where pep='" + PEPDB + "';"
> 
> and it fails just the same.
> 
> If I change the update to a select statement, it does not block.  If I
> leave the test update from psql running (blocked), and then exit the
> ISCS application, the update completes.  This also implies it is not
> just blocking within the application; it is blocking the entire public
> schema from any access, e.g., command line psql.  Even stranger, the
> update blocks itself, i.e., it never completes even though
> QSqlQuery::exec() returns true!
> 
> I have no idea of what to do next.  Here is the pertinent code snippet:
> 
> void SPMMainForm::customEvent( QCustomEvent * ce )
> {
> . . .
> 	if (ce->type() == 10002) { // This is a PEPUpdateThread termination event
> 		QListViewItem * LVI;
> 		int MaxThreads;
> 		bool success, NoErrors, SQTempExists = (so->SQEdit != 0);
> 		QSqlQuery SQTemp( QString::null, SQTempExists ? so->DbEdit : so->DbProd );
> //		SQTemp.setForwardOnly(true); // Awaiting a bug fix for ForwardOnly using MySQL
> 		UpdateThread * puth = (UpdateThread *)ce->data();
> 		puth = static_cast<UpdateThread *>(ce->data());
> 		if ( puth->running()) {
> 			puth->wait();
> 		}
> 		QString PEPDB;
> 		PEPDB = QDeepCopy<QString>(puth->PEP);
> 		PEPDB = PEPDB.replace("'", "''");
> 		NoErrors = (puth->ErrorCode.isEmpty() || (puth->ErrorCode.left(20) == "[PEP Update Warning]"));
> 		if (NoErrors || puth->Retry) { // either there was no error or we errored after a retry
> 			
> //			so->ThreadCounter->lock();
> 			so->OpenUpdateThreads--; // keeping track of open threads so we know when we are done
> //			so->ThreadCounter->unlock();
> 			
> 			// Update the dbVersion in the peps database table
> 			if ( ! so->SQProd->exec("update peps set dbversion=" + QString::number(puth->PEPDbVersion) + ", current=" + (puth->ErrorCode.isEmpty() ? so->True : so->False) + " where pep='" + PEPDB + "';")) {
> 				success = false;
> 
> 
> Can anyone please point me in the right direction? I was delighted to
> port this application from MySQL and really do not want to revert back
> to MySQL only.  Thanks - John
<snip>
Hello, all.  It was a brain cramp on my part (as expected!).  The logic
had a hole where, in an unusual set of circumstances where there were no
database changes to commit, a transaction was opened on the public
schema and not committed or rolled back.  The transaction hanging open
was causing the block.  Once I eliminated the dangling transactions, all
worked.  Sorry for the intrusion - John
-- 
John A. Sullivan III
Open Source Development Corporation
+1 207-985-7880
jsullivan at opensourcedevel.com

http://www.spiritualoutreach.com
Making Christianity intelligible to secular society




More information about the Qt-interest-old mailing list