2016-03-15 84 views
1

使用PHP和PDO我們連接到Microsoft SQL服務器。我們希望以READ UNCOMMITTED的形式運行一些連接。PHP PDO sqlsrv for SQL Server not entered 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這樣的輸出: READCOMMITTED READUNCOMMITTED

在Windows上: READCOMMITTED READCOMMITTED

注: 連接字符串是不同的,在Mac上這將是「DBLIB :主機= $主機名; dbname = $ dbname「

我試圖包括設置交易語句在同樣的說法,我測試它的設置,並得到相同的結果。

我也嘗試在連接時使用PDO :: SQLSRV的常量標誌來設置READ UNCOMMITTED,但是會引發奇怪的異常。

$pdo = new PDO ("sqlsrv:server=$hostname;database=$dbname",$username,$pw,[PDO::SQLSRV_TXN_READ_UNCOMMITTED]); 

這導致一個PDOException:「在自動提交模式下不能改變此驅動程序」

+0

什麼版本的MS SQL的你使用?什麼是驅動程序版本?和PHP版本?要爲您的連接檢索自動提交屬性的值,請嘗試:'echo $ pdo-> getAttribute(constant(「PDO :: ATTR_AUTOCOMMIT」));' – gofr1

+0

有趣的問題。我玩你的代碼,唯一的辦法是,當它按你的想法工作時,調用'$ pdo-> exec(「SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED」);'而不是準備好的語句。 '$ pdo-> query()'也不起作用。您還可以在創建PDO實例時更改隔離級別。文檔中描述了此路徑。 – kba

+0

這個工作,跳過準備做它。奇怪。我曾嘗試在創建時設置它,就像您在幾天前的編輯中看到的那樣會導致異常。 – Sean256

回答

0

你必須這樣設置的:

$isolationLevel = PDO::SQLSRV_TXN_READ_UNCOMMITTED; 

$pdo = new PDO("sqlsrv:server=$hostname;database=$dbname; TransactionIsolation=".$isolationLevel, $username,$pw);