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's Documentation 搜索了该主题,但找不到任何相关信息。

所以,我的问题是:对于这种缺乏事务支持(一些配置选项,甚至编辑 Doctrine 的 DBAL 源)是否有任何解决方法。

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

4

2 回答 2

1

This is a PDO exception that's thrown whenever you try to start a transaction on a non-transactional database via PDO::beginTransaction().

Doctrine will typically handle transactions by queuing them up internally in a unit of work, and then writing them as a single optimised query upon flush().

Unfortunaly when a unit of work is commited (via flush) it appears to begin a transaction for you.

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

Which as far as I can tell suspends auto-commit mode on whatever DB driver you're using and triggers the error your getting whenever you attempt to persist something.

In short it doesn't appear that doctrine supports non-transactional database interactions.

It appears some have tried to tinker with the Annotation driver to allow them to specify the engine type to be non-transactional. Not sure how well this would work with the underlying ORM though.

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

于 2012-05-18T13:43:26.170 回答
0

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

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

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

我还分叉了学说的 dbal github 项目,以包含一个使用 dblib 作为连接代理的自定义驱动程序。根据我的项目的依赖关系,将教义-dbal 锁定到版本 2.1.6,我创建了2.1.6 -dblib 版本,您可以在任何时候使用 dblib 的驱动程序。

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

于 2012-05-23T13:55:02.450 回答