Reputation: 175
For performance reasons I would like to persist a log object using mysql's INSERT DELAYED query.
Do you have any ideas how that could be performed using doctrine?
Upvotes: 3
Views: 1121
Reputation: 52483
As of MySQL 5.6.6, INSERT DELAYED is deprecated, and will be removed in a future release. Use INSERT (without DELAYED) instead.
With symfony2 you can perform a non-blocking database-operation by creating a listener/subscriber for the kernel.terminate
event and executing it in there.
This event is fired after the response has been sent. It's being used by monolog in the production environment for example.
Create a listener class first:
namespace Acme\Your;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\HttpKernel\Event\KernelEvent;
class LongOperationLogger
{
protected $om;
protected $data;
public function __construct(ObjectManager $om)
{
$this->om = $om;
}
public function setData($data)
{
$this->data = $data;
}
public function onKernelTerminate(KernelEvent $event)
{
// don't do anything if there is not data
if ( null !== $this->data ) {
return;
}
$logEntry = new LogEntry('I will not block the response.', $this->data);
$this->om->persist($logEntry);
$this->om->flush();
}
}
Then define it as a service and inject your object-manager:
# app/config/config.yml
services:
long_operation.logger:
class: Acme\Your\LongOperationLogger
tags:
- { name: kernel.event_listener, event: kernel.terminate }
arguments: [ "@doctrine.orm.entity_manager" ]
Finally, you can add data to the logger from inside a controller or some service which in turn activates and executes the database-operation in a non-blocking way after the response has been sent.
public function someAction()
{
// some condition
// if (...) {
// ...
// }
$this->get('long_operation.logger')->setData($whatever)
}
Upvotes: 5