In another issue (#995820: Exception sometimes when saving) it was discovered that apparently db_set_active() will commit the current transaction which then, of course, will always lead to an exception being thrown when the transaction object goes out of scope (because it tries to commit a transaction that doesn't exist any more).

The question now is: Is this a) intended and b) inevitable? If so, it should be somewhere documented that db_set_active() should not be called while a transaction is open. (Or conditions, under which this is possible, if there are any.)
Otherwise it would be great if this could somehow be fixed.

What I also discovered in the other issue is that this also happens if db_set_active() is called with the same key that is already active. Wouldn't it be possible to just let the function return if this is the case? I couldn't find any way to get the currently active key without calling db_set_active() itself, so this apparently can't be emulated from the "outside". (But that just as a side note, I know that this would be a different issue.)

Comments

Crell’s picture

It is not intended. I'm unclear on why that's happening so I don't know if it can be worked around.

drunken monkey’s picture

Oh. Hm. Then it maybe only occurs on MySQL databases?
Or, new thought: Maybe this only occurs when the database is not really switched? Completely uninformed guess: db_set_active() is called, a new connection to the same database is created, the MySQL server sees that and discards the old connection, committing all its transactions. (OK, that sounded a lot more convincing before I had written it down …) Would something like this be possible?

Crell’s picture

Status: Active » Postponed (maintainer needs more info)

db_set_active() doesn't do anything but call Database::setActiveConnection(). That, in turn, doesn't actually touch connection objects. It just plays with the string properties of Database and sets self::$activeKey.

There's seriously no way for that to touch transactions. Are you sure that *just* calling db_set_active() does that? You're not also running a query against that other connection?

drunken monkey’s picture

Status: Postponed (maintainer needs more info) » Closed (works as designed)

Sorry, my bad, I was completely on the wrong track, there. The cause for the problem seemingly was a CREATE/DROP TABLE statement, which I now learned implicitly commits transactions (and maybe also releases savepoints — couldn't really find a definitive statement on that).

Sorry for wasting your time. :-/