Download the PHP package mhujer/rabbit-mq-database-transaction-producer-bundle without Composer

On this page you can find all versions of the php package mhujer/rabbit-mq-database-transaction-producer-bundle. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package rabbit-mq-database-transaction-producer-bundle

RabbitMQ Database Transaction Producer Bundle

This package is a fork of vasek-purchart/rabbit-mq-database-transaction-producer-bundle maintained for newer PHP and Symfony versions.


Publish messages to RabbitMQ producer when database transaction was committed

Note: This bundle expects you are using Doctrine DBAL & ORM Bundle and RabbitMqBundle

The problem

Transactions in databases ensure that in a series of operations either all of them are "completed" or none of them is. This is very important for most applications, because otherwise their state becomes broken. That is why most database systems provide transactions (at least at some level). New problem arises, when you are using multiple systems, because there is usually no way to ensure transactional behavior for operations spanning all of them.

This bundle provides solution to mitigate the most common situations which originate from this problem when using RabbitMQ with an SQL database (through Doctrine). Both SQL databases and RabbitMQ have their own transactions, but there is no way to extend the transactions between the systems, which can lead to many erroneous situations, typically:

1) You publish an ID to the RabbitMQ queue, which should be processed asynchronously, but it was never committed to the database. 2) You publish an ID to the RabbitMQ queue, which should be processed asynchronously, but it was not yet committed to the database. 3) Everything is committed to the database, but the accompanying message was never sent to the queue.

This is even more common if you are using nested transactions, because then it is especially difficult to tell just by looking at "local" code, when the transaction will actually be committed.

That is precisely the case when using Doctrine ORM, because even when you call flush, you cannot be sure, that there is no open transaction wrapping this call.

What this bundle does

This bundle does not claim to "solve" the problem, because it's almost impossible, but it tries to mitigate most of the practical situations caused by the problem. When publishing messages to RabbitMQ, this bundle will check, if there is an open transaction (including nested) on the database connection and if not, it will send the message right away. But when it detects that there is an open transaction, then it will store the message and it will be sent only after and if all the transactions on the connection were committed.

When writing your code like in the example below, all the situations mentioned in the last section should not make problems:

The example represents an import which is split into items, which can then be processed asynchronously one by one. All persistence related operations are wrapped in a transaction using EntityManager::transactional(). First, the EntityManager is flushed, which means, that if any errors should arise when storing the data in the database, an exception will be thrown and the messages will never get published to RabbitMQ. If the data flushed by Doctrine was ok, then the messages will be published either immediately or after all nested transactions are committed.

This ensures that the data, on which the RabbitMQ messages are based will always be in the database before the messages are published, therefore solving the first two situations from the previous section.

The third situation - that the data is saved to the database, but the RabbitMQ message is never published - can unfortunately still occur - this will happen if there is a problem in the application after the commit and between the messages are published. But since the publishing logic is very simple and there is no business logic involved, this should almost never happen, the most common case is probably that the RabbitMQ instance is not reachable.

Configuration

Configuration structure with listed default values:

Custom connection class

Doctrine DBAL does not provide any way to add features to Doctrine\DBAL\Connection using composition, so that added functionality can be combined from multiple sources. The only way to extend the functionality is trough extending the original class and configuring Doctrine to use that class instead using the dbal.wrapper_class configuration option.

If you are already using custom connection implementation, you have to make sure it implements VasekPurchart\RabbitMqDatabaseTransactionProducerBundle\Doctrine\Connection\AfterCommitCallbacksConnection in order to be compatible with this bundle, namely implement addAfterCommitCallback method and make sure the callbacks are triggered after the transaction is committed.

If you are not using any custom implementation, this bundle will provide implementation, which adds the callbacks behavior and on top of that provide logging for exceptions originating from called callbacks.

Services overloading

You can also override services used internally, for example if you use a non standard logger, you can provide custom instance with an alias:

Installation

Install package mhujer/rabbit-mq-database-transaction-producer-bundle with Composer:

Register the bundle in your application:


All versions of rabbit-mq-database-transaction-producer-bundle with dependencies

PHP Build Version
Package Version
Requires php Version ~7.4 || ~8.0
doctrine/doctrine-bundle Version ~2.2
php-amqplib/rabbitmq-bundle Version ~2.2
psr/log Version ~1.0
symfony/config Version ~4.4|^5.4|^6.0
symfony/dependency-injection Version ~4.4|^5.4|^6.0
symfony/http-kernel Version ~4.4|^5.4|^6.0
symfony/yaml Version ~4.4|^5.4|^6.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package mhujer/rabbit-mq-database-transaction-producer-bundle contains the following files

Loading the files please wait ....