2

永続化またはフラッシュを呼び出さずにデータベースに永続化されているドクトリンエンティティがあります。

私は問題を非常に簡単に以下で再現することができました。ご覧のとおり、このスクリプトはMyEntityというデータベーステーブルから行をロードし、行のフィールドを属性として持つphpオブジェクトを取得します。次に、スクリプトは属性の1つを変更しますが、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;
    }

?>
4

1 に答える 1

2

Doctrineマニュアル:9。トランザクションと並行性-> 9.1.2。アプローチ2:明示的に(セクション下部):

Connection#transactional($ func)とEntityManager#transactional($ func)の違いは、後者の抽象化は、トランザクションのコミット前にEntityManagerをフラッシュし、例外が発生したときにEntityManagerを適切に閉じることです(トランザクションのロールバックに加えて)。

したがってEntityManager#transactional($func)、トランザクションコミットの前にEntityManagerをフラッシュします($func呼び出しが成功した場合-あなたの場合)。

于 2012-12-19T19:32:15.623 に答える