Symfony2 + Doctrine2 + SQL Server - 事务支持

3
我正在使用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个回答

1

这是一个PDO异常,每当您尝试通过PDO :: beginTransaction()在非事务性数据库上启动事务时抛出。

Doctrine通常通过在工作单元中将它们排队,然后在flush()时将它们作为单个优化查询编写来处理事务。

不幸的是,当工作单元提交(通过flush)时,它似乎会自动为您开始一个事务。

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

据我所知,这会暂停您正在使用的任何数据库驱动程序上的自动提交模式,并在您尝试持久化某些内容时触发错误。
简而言之,Doctrine似乎不支持非事务性数据库交互。
看起来有些人已经尝试通过调整注释驱动程序来允许他们指定引擎类型为非事务性。但是不确定这是否能很好地与底层ORM配合使用。

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


谢谢您的解释。我确实没有深入研究Doctrine源代码中的UnitOfWork类,现在变得更加清晰了。这是一步一步的集成过程,我发现了很多问题。但是我发现了一个捆绑包(PDODblibBundle),它提供了Driver和Connection类来处理MSSQL,显然支持事务。我会尝试那种方法,并在有更具体的见解时更新答案。感谢您的解释。 - Tiago

0
我发现我遇到的问题是由于我使用的驱动程序的日期时间格式引起的。为了解决这个问题,我不得不删除日期的时区部分,并在捆绑引导代码中覆盖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驱动程序时使用它。

我在我的分支中使用了PDODblibBundle的代码库。在其Connection类中,执行BEGIN TRANSACTION命令,但我认为无法回滚。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接