-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Commits silently fail after node quorum rejects changes (Percona cluster + Galera plugin) #3175
Comments
Looks like all implementors of the As part of @tonykiselis what about rollbacks? Besides having been called in a wrong state, can it fail and therefore have to be handled by the caller? |
I found that weird too. Although, it's also kinda weird that in most cases it should throw exception so you can wrap commit in a Well, there is no rollback. I mean, you can This happens, as I've mentioned, when multiple nodes try to write into same record. Nodes communicate and ask other members of the cluster if it's okey for them to commit. If some other node currently has that row locked, transaction doesn't proceed and is discarded. However, from code side in doctrine, commit does not throw exception on this part and you end up with nasty situation. Currently hacking around the problem by extending |
According to the method signature, dbal/lib/Doctrine/DBAL/Driver/Connection.php Lines 85 to 90 in 0d26c7f
neither of the implementors are supposed to throw exceptions but are supposed to return booleans. This indeed is not OO-friendly and most likely was borrowed from PDO.
Sorry, I should have asked it clearer. My question was, should we fix the dbal/lib/Doctrine/DBAL/Driver/Connection.php Lines 92 to 97 in 0d26c7f
suggests that implementors should return a boolean value, however, none (or at least not all) of them do. From your experience with Percona, is it possible that a rollback fails in the way a caller can/should handle the failure? |
Our issue, well, of which we are at least aware of now is with commit silent failures in described circumstances. Cannot really comment on rollbacks. I would need to check on that, now that you've mentioned it. |
I only have one idea: violating an initially deferred foreign key that fails on COMMIT, not after the statement which violated the constraint. |
Besides the reported bug, I see the following issues which don't help to fix it:
With the above said and the fact a commit failure cannot be consistently reproduced across the platforms, can we just have a patch like this without any tests? /**
* Commits the current transaction.
*
- * @return void
+ * {@inheritDoc}
*
* @throws \Doctrine\DBAL\ConnectionException If the commit failed due to no active transaction or
* because the transaction was marked for rollback only.
@@ -1305,12 +1305,13 @@ class Connection implements DriverConnection
$this->connect();
$logger = $this->_config->getSQLLogger();
+ $result = true;
if ($this->_transactionNestingLevel == 1) {
if ($logger) {
$logger->startQuery('"COMMIT"');
}
- $this->_conn->commit();
+ $result = $this->_conn->commit();
if ($logger) {
$logger->stopQuery();
}
@@ -1329,6 +1330,8 @@ class Connection implements DriverConnection
if (false === $this->autoCommit && 0 === $this->_transactionNestingLevel) {
$this->beginTransaction();
}
+
+ return $result;
}
/** |
This is probably php/PDO issue: https://bugs.php.net/bug.php?id=66528 |
I'm closing this issue since the originally suggested change has been implemented in #3588. If the problem still persists, we can reopen it or file a new more specific issue. |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Bug Report
Summary
Commit from code side passes as if commit was successful when no data was written into the database. Issue reveals itself when Doctrine is being used with Percona multi-master cluster with galera plugin.
Commits silently fail. You end up with "lost data" as rest of the code executes as if everything went fine.
Establish Percona database cluster with galera plugin. Run multiple queries which would use Pessimistic lock to different nodes at the same time. Durining the quorum the requested will be rejected. However, the transanction from code side will pass as if commit was successful despite of it.
To fix: Doctrine\DBAL\Connection::commit() consistently returns false when commit didn't happen. However, this information is tightly wrapped and inaccessible from the Doctrine's API.
Best in my opinion: thow exception on Doctrine\ORM\Connection::commit() when it calls Doctrine\DBAL\Connection::commit() and it returns false. This will uphold the consistency instead of dealing with bool values.
To have exception being thrown after failure to commit in this instance.
The text was updated successfully, but these errors were encountered: