Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 5

Qt-interest Archive, February 2008
How can I tell if a transaction has already been started on a database?


Message 1 in thread

Hi Everyone, 

I have many complex dialogs and use common routines for each table type to performs the updates required. The routines currently take a database parameter. The problem is that I can't find a method to know whether a transaction has been already been started on the database. I am using the IBase driver exclusively, and doing transaction twice (in a nested routine) then commit twice results in a error on the second commit. What I would like is roughly: 

TOrderList.saveDB(QSqlDatabase db) {
	bool inTrans = db.inTransaction();
	if (!inTrans)
		db.transaction();

	... do updates

	if (!inTrans)
		db.commit();
}

TCustomerList.saveDB(QSqlDatabase db) {
	bool inTrans = db.inTransaction();
	if (!inTrans)
		db.transaction();

	for each customer {
		...
		customer.orderList.saveDB(db);
	}

	if (!inTrans)
		db.commit();
}

Thanks in advance. 

Tony Rietwyk

--
 [ signature omitted ] 

Message 2 in thread

Hi Tom,
Do You think using recursive Transactions is a really good idea?
Some database systems doesn't support such kind of operation at all (e.g. SqLite).
Others did (like Microsoft Sql Server).
So Your implementation is very database depending...

Best regards
Karl-Heinhz

> -----UrsprÃngliche Nachricht-----
> Von: Tony Rietwyk [mailto:tony.rietwyk@xxxxxxxxxxxxxxxx]
> Gesendet: Sonntag, 24. Februar 2008 04:09
> An: qt-interest@xxxxxxxxxxxxx
> Betreff: How can I tell if a transaction has already been started on a
> database?
> 
> Hi Everyone,
> 
> I have many complex dialogs and use common routines for each table type
> to performs the updates required. The routines currently take a
> database parameter. The problem is that I can't find a method to know
> whether a transaction has been already been started on the database. I
> am using the IBase driver exclusively, and doing transaction twice (in
> a nested routine) then commit twice results in a error on the second
> commit. What I would like is roughly:
> 
> TOrderList.saveDB(QSqlDatabase db) {
> 	bool inTrans = db.inTransaction();
> 	if (!inTrans)
> 		db.transaction();
> 
> 	... do updates
> 
> 	if (!inTrans)
> 		db.commit();
> }
> 
> TCustomerList.saveDB(QSqlDatabase db) {
> 	bool inTrans = db.inTransaction();
> 	if (!inTrans)
> 		db.transaction();
> 
> 	for each customer {
> 		...
> 		customer.orderList.saveDB(db);
> 	}
> 
> 	if (!inTrans)
> 		db.commit();
> }
> 
> Thanks in advance.
> 
> Tony Rietwyk
> 
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/

--
 [ signature omitted ] 

Message 3 in thread

Tony Rietwyk wrote:

>  What I would like is roughly: 
> 
> TOrderList.saveDB(QSqlDatabase db) {
> 	bool inTrans = db.inTransaction();
> 	if (!inTrans)
> 		db.transaction();
> 
> 	... do updates
> 
> 	if (!inTrans)
> 		db.commit();
> }
> 
> TCustomerList.saveDB(QSqlDatabase db) {
> 	bool inTrans = db.inTransaction();
> 	if (!inTrans)
> 		db.transaction();
> 
> 	for each customer {
> 		...
> 		customer.orderList.saveDB(db);
> 	}
> 
> 	if (!inTrans)
> 		db.commit();
> }

I wrote a wrapper class that does this, more or less.
It's pretty trivial to record the transaction state and
commit and rollback as appropriate. The only possible
problem I could foresee is that of thread-safety, but
since each thread must have its own db connection, this
doesn't arise in practise.

As someone else pointed out, in general, you shouldn't
try to nest transactions as that will break some drivers.

-- 
 [ signature omitted ] 

Message 4 in thread

Stephan wrote on Sunday, 24 February 2008 20:33

> Tony Rietwyk wrote:
> 
> >  What I would like is roughly: 
> > 
> > TOrderList.saveDB(QSqlDatabase db) {
> > 	bool inTrans = db.inTransaction();
> > 	if (!inTrans)
> > 		db.transaction();
> > 
> > 	... do updates
> > 
> > 	if (!inTrans)
> > 		db.commit();
> > }
> > 
> > TCustomerList.saveDB(QSqlDatabase db) {
> > 	bool inTrans = db.inTransaction();
> > 	if (!inTrans)
> > 		db.transaction();
> > 
> > 	for each customer {
> > 		...
> > 		customer.orderList.saveDB(db);
> > 	}
> > 
> > 	if (!inTrans)
> > 		db.commit();
> > }
> 
> I wrote a wrapper class that does this, more or less.
> It's pretty trivial to record the transaction state and
> commit and rollback as appropriate. The only possible
> problem I could foresee is that of thread-safety, but
> since each thread must have its own db connection, this
> doesn't arise in practise.
> 
> As someone else pointed out, in general, you shouldn't
> try to nest transactions as that will break some drivers.
> 
> -- 
> Regards
> 
> Steve Collyer
> Netspinner Ltd

Thanks Stephan and Karl-Heinz, 

I understand that nested transactions are not a good idea. 

I thought the code shows that I am trying to avoid that situation. 

I have implemented a similar wrapper. 

Thanks, 

Tony. 

--
 [ signature omitted ]