For performance reasons I would like to persist a log object using mysql's INSERT DELAYED query.
出于性能原因,我希望使用mysql的INSERT delay查询来持久化日志对象。
Do you have any ideas how that could be performed using doctrine?
你知道怎么用教义来执行吗?
1 个解决方案
#1
5
Why you probably shouldn't use INSERT DELAYED:
As of MySQL 5.6.6, INSERT DELAYED is deprecated, and will be removed in a future release. Use INSERT (without DELAYED) instead.
从MySQL 5.6.6开始,插入延迟被弃用,并将在以后的版本中删除。使用插入(不延迟)代替。
(官方文档)
The symfony2 solution:
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.
使用symfony2,您可以通过为内核创建侦听器/订阅器来执行非阻塞数据库操作。终止事件并在其中执行它。
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)
}
#1
5
Why you probably shouldn't use INSERT DELAYED:
As of MySQL 5.6.6, INSERT DELAYED is deprecated, and will be removed in a future release. Use INSERT (without DELAYED) instead.
从MySQL 5.6.6开始,插入延迟被弃用,并将在以后的版本中删除。使用插入(不延迟)代替。
(官方文档)
The symfony2 solution:
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.
使用symfony2,您可以通过为内核创建侦听器/订阅器来执行非阻塞数据库操作。终止事件并在其中执行它。
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)
}