Reputation: 31233
I have following problem.
I have database connection that are recycled (put back into pool).
For example:
{
session sql(conn_str); // take connection from pool
sql.exec("insert into ...")
} // at the end of the scope return connection to pool
However in certain cases recycling may be wrong - for example disconnect, or some other significant error.
So I want to automatically prevent from the connection being recycled. I want to
implement following technique using std::uncaught_exception
- so the exec() function
would detect exceptions and prevent recycling:
session::exec(...)
{
guard g(this)
real_exec(...);
}
Where guard:
class guard {
public:
guard(session *self) : self_(self) {}
~guard() {
if(std::uncaught_exception()) {
self->mark_as_connection_that_should_not_go_to_pool();
}
}
}
Now, I'm aware of http://www.gotw.ca/gotw/047.htm that does not recommend using
std::uncaught_exception
on the other case I don't see any wrong with my code also,
the provides examples discussed.
Are there any possible problems with this code.
Note:
Upvotes: 1
Views: 221
Reputation: 308158
I don't see any advantage to your method over something more straightforward:
session::exec()
{
try
{
real_exec();
}
catch(...)
{
mark_as_connection_that_should_not_go_to_pool();
throw;
}
}
If the verboseness of this solution bothers you, I will note that they haven't ripped macros out of C++ yet. I wouldn't prefer this version as it masks the underlying code and is kind of ugly.
#define GUARD try {
#define ENDGUARD } catch(...) { mark_as_connection_that_should_not_go_to_pool(); throw; }
session::exec()
{
GUARD
real_exec();
ENDGUARD
}
Another possibility is to assume failure until success is achieved.
session::exec()
{
mark_as_connection_that_should_not_go_to_pool();
real_exec();
mark_as_connection_that_may_go_to_pool();
}
Finally to answer the question of whether uncaught_exception
will work as you've outlined, I will quote from Microsoft's documentation of the function:
In particular, uncaught_exception will return true when called from a destructor that is being invoked during an exception unwind.
It appears to do exactly what you'd expect.
Upvotes: 2