【发布时间】:2016-07-01 06:08:11
【问题描述】:
我们使用 PHP 和 PDO 连接到 Microsoft SQL 服务器。我们希望以 READ UNCOMMITTED 运行我们的一些连接。
我的大部分开发工作都是在 Mac 上完成的,并在 Windows 机器上进行测试/部署。我发现在 Mac 或 Linux 上使用 dblib(FreeTDS) 进入 READ UNCOMMITTED 可以正常工作,但在使用 sqlsrv(官方 MS 驱动程序)的 Windows 上却没有。
这是我为测试它而编写的一个简单脚本。
$pdo = new PDO ("sqlsrv:server=$hostname;database=$dbname",$username,$pw);
$stmtIsolationLevel = $pdo->prepare(
"SELECT CASE transaction_isolation_level
WHEN 1 THEN 'ReadUncommitted'
WHEN 2 THEN 'ReadCommitted'
END AS TRANSACTION_ISOLATION_LEVEL
FROM sys.dm_exec_sessions
where session_id = @@SPID"
);
$stmtSetUncommitted = $pdo->prepare("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
//output transaction level
$stmtIsolationLevel->execute();
$results = $stmtIsolationLevel->fetchAll(PDO::FETCH_ASSOC);
echo $results[0]['TRANSACTION_ISOLATION_LEVEL'] . "\n";
//set to READ UNCOMMITTED"
$stmtSetUncommitted->execute();
$results = $stmtSetUncommitted->fetchAll(PDO::FETCH_ASSOC);
//output transaction level
$stmtIsolationLevel->execute();
$results = $stmtIsolationLevel->fetchAll(PDO::FETCH_ASSOC);
echo $results[0]['TRANSACTION_ISOLATION_LEVEL'] . "\n";
在 Mac 或 Linux 上,此输出: 已提交 读未提交
在 Windows 上: 已提交 已提交
注意事项: 连接字符串不同,在 Mac 上它会是 "dblib:host=$hostname;dbname=$dbname"
我尝试将 set transaction 语句包含在我测试它的设置的同一语句中,我得到了相同的结果。
我还尝试使用 PDO::SQLSRV 的常量标志在连接时设置 READ UNCOMMITTED,但这会引发奇怪的异常。
$pdo = new PDO ("sqlsrv:server=$hostname;database=$dbname",$username,$pw,[PDO::SQLSRV_TXN_READ_UNCOMMITTED]);
这会导致 PDOException:“无法更改此驱动程序的自动提交模式”
【问题讨论】:
-
您使用什么版本的 MS SQL?什么是驱动版本?和PHP版本?要检索连接的自动提交属性值,请尝试:
echo $pdo->getAttribute(constant("PDO::ATTR_AUTOCOMMIT")); -
有趣的问题。我使用了您的代码,当它按您的意愿工作时,唯一的方法是调用
$pdo->exec("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");而不是准备好的语句。$pdo->query()也没有用。您还可以在创建 PDO 实例时更改隔离级别。此路径在 doc 中进行了描述。 -
行得通,跳过准备好的就行了。奇怪的。正如您在几天前的编辑中看到的那样,我确实尝试在创建时设置它,这会导致异常。
-
是的,我知道。您以不好的方式调用 PDO 构造函数。 https://stackoverflow.com/questions/36018320/pdoexception-the-auto-commit-mode-cannot-be-changed-for-this-driver.
标签: php sql-server pdo sqlsrv