小智 15
对于Symfony 2 使用原始sql:
$em->getConnection()->prepare("INSERT INTO table SET
some_fields = "some data", created_at = NOW()
ON DUPLICATE KEY UPDATE
some_fields = "some data", updated_at = NOW()
")->execute();
Run Code Online (Sandbox Code Playgroud)
你不能。目前 Doctrine 不支持它。
您可以做的是通过检查实体是否存在并相应地更新/创建它来模仿 MySQL 的操作:
$em = $this->getEntityManager();
// Prevent race conditions by putting this into a transaction.
$em->transactional(function($em) use ($content, $type) {
// Use pessimistic write lock when selecting.
$counter = $em->createQueryBuilder()
->select('MyBundle:MyCounter', 'c')
->where('c.content = :content', 'c.type = :type')
->setParameters(['content' => $content, 'type' => $type])
->setLockMode(\Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE);
->getQuery()
->getResult()
;
// Update if existing.
if ($counter) {
$counter->increase();
} else {
// Create otherwise.
$newCounter = new Counter($content, $type, 1);
$em->persist($newCounter);
}
});
Run Code Online (Sandbox Code Playgroud)
如果记录存在,PESSIMISTIC_WRITE请确保在我们更新它时它不会被任何人(例如其他线程)更新。
尽管您需要在每次更新时检查实体是否存在,但这只是“如果存在则更新,如果不存在则创建”的简单再现。
正如评论中指出的,如果记录不存在,这不会阻止竞争条件:如果在选择和插入之间插入具有相同键的行,则会遇到重复键异常。
但考虑到这需要独立于数据库的限制,因此使用 Doctrine 编写而不是使用本机 SQL,这在某些情况下可能会有所帮助。
参考:
| 归档时间: |
|
| 查看次数: |
19751 次 |
| 最近记录: |