gpt4 book ai didi

php - 为什么空交易会保留我的实体(原则)?

转载 作者:行者123 更新时间:2023-11-29 02:30:30 26 4
gpt4 key购买 nike

我有一个原则实体,无需调用 persist 或 flush 即可持久保存到数据库中。

我在下面很简单地重现了这个问题。正如您将看到的,此脚本从名为 MyEntity 的数据库表中加载一行,并获取一个以该行的字段作为属性的 php 对象。然后脚本更改其中一个属性,但不调用 persist 或 flush。然后脚本创建一个什么都不做的空事务。奇怪的是,这使得对象持久化,因为对 php 对象所做的更改也在数据库中进行。我没想到这个脚本会对数据库进行任何更改。

这里发生了什么?

请注意,如果我删除空事务,问题就会消失,并且不会对数据库进行任何更改。

这是代码(test.php):

<?php

use Doctrine\ORM\Tools\Setup;

require_once("Doctrine/ORM/Tools/Setup.php");
Setup::registerAutoloadPEAR();

$classloader = new Doctrine\Common\ClassLoader('testEntities', __DIR__);
$classloader->register();

$paths = array();
$isDevMode = true;
$config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode);
$dbParams = array("driver" => "pdo_mysql",
"host" => "localhost",
"user" => "username",
"password" => "password",
"dbname" => "databaseName",
"charset" => "utf8");

$em = \Doctrine\ORM\EntityManager::create($dbParams, $config);
$em->getConnection()->exec("SET NAMES UTF8");

$matches = $em->getRepository('testEntities\\MyEntity')->findBy(array('ID' => 1));
echo("<pre>");

if (!empty($matches)) {
$object = $matches[0];
print_r($object);
$object->Content = "WILL IT BLEND?";
print_r($object);
}
$em->transactional(function($em) {
// Nothing happens here, but if I comment out the call to transactional, the behaviour of the script changes.
});

echo("</pre>Done!");
?>

在数据库中创建并填充 MyEntity 表:

CREATE TABLE `MyEntity` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Content` varchar(500) COLLATE utf8_swedish_ci NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci;

INSERT INTO MyEntity (ID, Content) VALUES (NULL, "Hello World");

创建 MyEntity 学说实体(testEntities\MyEntity.php):

<?php

namespace testEntities;

/** @Entity @Table(name="MyEntity")*/
class MyEntity
{
/**
* @Id @GeneratedValue(strategy="AUTO") @Column(type="integer")
*/
public $ID;

/**
* @Column(type="string", length=500)
*/
public $Content;
}

?>

最佳答案

Doctrine 手册:9. 事务和并发 -> 9.1.2. Approach 2: Explicitly (在底部):

The difference between Connection#transactional($func) and EntityManager#transactional($func) is that the latter abstraction flushes the EntityManager prior to transaction commit and also closes the EntityManager properly when an exception occurs (in addition to rolling back the transaction).

因此:EntityManager#transactional($func) 在事务提交之前刷新 EntityManager(如果 $func 调用成功 - 您的情况)。

关于php - 为什么空交易会保留我的实体(原则)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13959493/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com