magento2: “Asymmetric transaction rollback error” if commit callbacks throw exceptions

Preconditions

  1. All current Magento 2 versions (2.0, 2.1.1)

Steps to reproduce

  1. Let a commit callback throw an exception

    Example:

    • create a new search engine
    <type name="Magento\Search\Model\AdapterFactory">
      <arguments>
        <argument name="adapters" xsi:type="array">
          <item name="dummy" xsi:type="string">Magento\Framework\Search\Adapter\Mysql\Adapter</item>
        </argument>
      </arguments>
    </type>
    
    • Do not register a corresponding indexer handler for Magento\CatalogSearch\Model\Indexer\IndexerHandlerFactory
    • The commit callback from the fulltext indexer plugin will cause an exception “There is no such indexer handler: dummy”
  2. Trigger this commit (for example, save a product)

Expected result

  1. Exception from the commit callback is thrown and can be catched later (for ex. by PHPUnit)

Actual result

  1. rollback() is called after commit() already has been called for the same transaction, resulting in an “Asymmetric transaction rollback error” exception when Magento tries to commit or rollback the last transaction on the stack.

Possible solution

  1. create a new exception type for exceptions during commit callbacks, AfterCommitException

  2. Replace throw $e with throw new AfterCommitException(null, null, $e); in AbstractResource::commit()

  3. In plugins that register commit callbacks, handle these exceptions separately:

        } catch (AfterCommitException $e) {
            throw $e->getPrevious();
        } catch (\Exception $e) {
            $productResource->rollBack();
            throw $e;
        }
    

Please let me know if this solution would be acceptable, before I create a PR

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 15
  • Comments: 29 (24 by maintainers)

Commits related to this issue

Most upvoted comments

I’ve have created PR #9955 for this but I’m not very clear on how to move this ticket into the PR created column of the Project Board - or is this something that board moderators do? I would imagine that its a drag and drop functionality for those with permissions? (Which I mention only to stop someone else pointlessly starting work on this…)

@dzmcclur the steps you’ve followed mean that you have eliminated plugins as the source of the rollback… you’ll need to debug to find the true cause… This thread isn’t the right medium for helping you. May I suggest posting on magento.stackexchange.com

@waynetheisinger the confusing part of my answer is, what I meant with it. Escalating exceptions IS a problem (the one described in the issue), so it’s better to take the alternative.

@maghamed generally I would prefer escalating exceptions as high as possible over logging them silently and move on, but in this case it’s really a problem. I like your solution, it’s more stable than my original proposal.

Ideally, Commit Collback operations are asynchronous by their nature.

that’s also a good point!

Yes. I see the team is already handling the PR. Good job!