Symfony2 + Doctrine2 + SQL Server - 事务支持

时间:2012-05-17 17:44:50

标签: sql-server transactions symfony doctrine-orm

我正在Symfony2中开发一个连接到SQL Server实例的私有企业应用程序。在处理SQL Server时我遇到了很多问题,但到目前为止我已经管理过它。我正在使用FreeTDS + DBLib连接到SQL Server实例,并且此驱动程序不支持事务。这引出了以下问题:

每当我试图坚持一个对象时,Symfony(或Doctrine)抱怨:

request.CRITICAL: 
    PDOException: 
        This driver doesn't support transactions (uncaught exception) at /.../Doctrine/DBAL/Connection.php line 858

我的第一个是禁用交易,因为我通过应用程序进行的数据修改很少。我通过Doctrine的文档搜索了这个主题,但是我找不到相关的信息。

所以,我的问题是:是否存在缺少事务支持的解决方法(某些配置选项,甚至编辑Doctrine的DBAL源)。

并且:转换到Propel会更顺畅吗?我在他们的网站上看到他们支持SQL Server,并且有关于如何配置Propel以便正确使用它的文档。

2 个答案:

答案 0 :(得分:1)

这是一个PDO异常,只要您尝试通过PDO :: beginTransaction()在非事务性数据库上启动事务,就会抛出此异常。

Doctrine通常会通过在工作单元内部对它们进行排队来处理事务,然后在flush()上将它们写为单个优化查询。

不幸的是,当一个工作单元被提交(通过刷新)时,它似乎开始为你做交易。

//UnitOfWork::commit($entity = null);
$conn->beginTransaction();

据我所知,无论你使用什么数据库驱动程序,都会暂停自动提交模式,并在你尝试持久化时触发错误。

简而言之,似乎学说不支持非事务性数据库交互。

似乎有些人试图修改Annotation驱动程序,以允许它们将引擎类型指定为非事务性的。不知道这对底层ORM有多好。

http://www.doctrine-project.org/jira/browse/DDC-972

答案 1 :(得分:0)

我发现我遇到的问题是因为我使用的驱动程序的日期时间格式。为了克服这个问题,我不得不删除日期的Timezone部分,并覆盖bundle bootstrap代码中的DateTimeType:

\Doctrine\DBAL\Types\Type::overrideType(
    "datetime", 
    "Doctrine\DBAL\Types\VarDateTimeType"
);

\Doctrine\DBAL\Types\Type::overrideType(
    "date", 
    "Doctrine\DBAL\Types\VarDateTimeType"
);

我还分配了doctrine的dbal github项目,以包含一个使用dblib作为连接代理的自定义驱动程序。遵循我的项目依赖关系,将doctrine-dbal锁定到版本2.1.6,我创建了版本2.1.6-dblib,只要你想让dblib的驱动程序可用,你就可以使用它。

我在我的fork中使用了PDODblibBundle的代码库。在Connection类中,执行BEGIN TRANSACTION命令,但我相信不可能回滚。