Trying to figure out if otl_connect::logoff() is called automatically when an otl_connect object goes out of scope, I found this piece of code in otl_connect::~otl_connect() at line 16383 (nice line number...) in otlv4.h version 4.0.321:
Is this the intended behaviour - not calling logoff() at all if OTL_DESTRUCTORS_DO_NOT_THROW is not defined? I would have expected only the try - catch block to be removed in that case, but the actual call to logoff() to stay.
I can see a reason for not wanting to throw exceptions from this destructor if the otl_connect object is declared at global scope, but maybe that's a reason for always catching exceptions from this destructor, rather than changing its cleanup semantics in such a radical way.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
which is otl_connect you looked at is derived from. So, no need to panic. Try the following code and follow the otl_connect's destructor's call chain in the debugger:
include <iostream>
using namespace std;
define OTL_ODBC_MSSQL_2008
include <otlv4.h>
int main()
{
otl_connect::otl_initialize(); // initialize OCI environment
try{
otl_connect db;
db.rlogon("scott/tiger@mssql2008"); // connect to Oracle
}
catch(otl_exception& p){ // intercept OTL exceptions
cerr<<p.msg<<endl; // print out error message
cerr<<p.stm_text<<endl; // print out SQL that caused the error
cerr<<p.var_info<<endl; // print out the variable that caused the error
}
return 0;
}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If I understand it correctly:
- with OTL_DESTRUCTORS_DO_NOT_THROW defined, otl_connect::logoff() will be called first, and it will end up calling otl_odbc_connect::logoff() (in the case of ODBC);
- without OTL_DESTRUCTORS_DO_NOT_THROW, only otl_odbc_connect::logoff() will be called eventually, from the base class destructor.
In the first case, otl_odbc_connect::logoff() will be called a second time, from the base class destructor, but you're relying on the connected flag to prevent it from running twice, thus no chance of uncaught exceptions; fair enough.
However, there's a bunch of stuff that, as far as I can tell, happens only in otl_connect::logoff(), which will be called in the first case, but not in the second - for example, rollback() if OTL_ROLLS_BACK_BEFORE_LOGOFF is defined. Is that OK?
(still not panicking, no worries)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Well, there's that thing I talked about in the last paragraph above. Basically, it looks like OTL_ROLLS_BACK_BEFORE_LOGOFF, for example, won't work if OTL_DESTRUCTORS_DO_NOT_THROW is not defined.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Strangely enough, my last reply didn't get through to the OTL forum. I said that I was fixing the problem and that the fix would be in OTL 4.0.322, which is already released.
Sergei
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Trying to figure out if
otl_connect::logoff()
is called automatically when anotl_connect
object goes out of scope, I found this piece of code inotl_connect::~otl_connect()
at line 16383 (nice line number...) in otlv4.h version 4.0.321:Is this the intended behaviour - not calling
logoff()
at all ifOTL_DESTRUCTORS_DO_NOT_THROW
is not defined? I would have expected only thetry
-catch
block to be removed in that case, but the actual call tologoff()
to stay.I can see a reason for not wanting to throw exceptions from this destructor if the
otl_connect
object is declared at global scope, but maybe that's a reason for always catching exceptions from this destructor, rather than changing its cleanup semantics in such a radical way.logoff() is called in here
virtual ~otl_tmpl_connect() OTL_THROWS_OTL_EXCEPTION
{
logoff();
}
which is otl_connect you looked at is derived from. So, no need to panic. Try the following code and follow the otl_connect's destructor's call chain in the debugger:
include <iostream>
using namespace std;
define OTL_ODBC_MSSQL_2008
include <otlv4.h>
int main()
{
otl_connect::otl_initialize(); // initialize OCI environment
try{
otl_connect db;
db.rlogon("scott/tiger@mssql2008"); // connect to Oracle
}
catch(otl_exception& p){ // intercept OTL exceptions
cerr<<p.msg<<endl; // print out error message
cerr<<p.stm_text<<endl; // print out SQL that caused the error
cerr<<p.var_info<<endl; // print out the variable that caused the error
}
return 0;
}
OK, got it, not panicking, but still...
If I understand it correctly:
- with
OTL_DESTRUCTORS_DO_NOT_THROW
defined,otl_connect::logoff()
will be called first, and it will end up callingotl_odbc_connect::logoff()
(in the case of ODBC);- without
OTL_DESTRUCTORS_DO_NOT_THROW
, onlyotl_odbc_connect::logoff()
will be called eventually, from the base class destructor.In the first case,
otl_odbc_connect::logoff()
will be called a second time, from the base class destructor, but you're relying on theconnected
flag to prevent it from running twice, thus no chance of uncaught exceptions; fair enough.However, there's a bunch of stuff that, as far as I can tell, happens only in
otl_connect::logoff()
, which will be called in the first case, but not in the second - for example,rollback()
ifOTL_ROLLS_BACK_BEFORE_LOGOFF
is defined. Is that OK?(still not panicking, no worries)
Yes, it relies on the connected flag. If you find any flaw in the logic, let me know, and I'll fix it.
Well, there's that thing I talked about in the last paragraph above. Basically, it looks like
OTL_ROLLS_BACK_BEFORE_LOGOFF
, for example, won't work ifOTL_DESTRUCTORS_DO_NOT_THROW
is not defined.Sergei, did you get a chance to look at the above?
Bogdan,
Strangely enough, my last reply didn't get through to the OTL forum. I said that I was fixing the problem and that the fix would be in OTL 4.0.322, which is already released.
Sergei
Oh, that's great, Sergei. Thanks a lot, now that was a really quick fix.
I hadn't noticed the new release, my mistake. Is there a RSS feed I can subscribe to for OTL releases?
Let's take this discussion offline. Send an email to my gmail account (can be found at the bottom of any OTL page).