Quantcast
Channel: Microsoft Drivers for PHP for SQL Server forum
Viewing all articles
Browse latest Browse all 391

Unexpected error "New transaction is not allowed because there are other threads running in the session"

$
0
0
Hi,

I've found a problem that appears to be a driver or database bug.

While fetching a resultset in non-transactional context it is not allowed to start a transaction - this is well-known, you'll get a "New transaction is not allowed because there are other threads running in the session."

However, when using a specific type of COUNT()-query that should only have exactly one result record, the resultset appears to be left open even when sqlsrv_fetch_array() has been called thus leading to unexpected failures when calling sqlsrv_begin_transaction() afterwards.

I have written a reproduction script, please check:

###################################################################
<?php

try {
    $db_conn = get_db_conn_sqlsrv();

    echo '<br>php version: [' . phpversion() . ']';
    echo '<br>sapi name: [' . php_sapi_name() . ']';
    echo '<br>sqlsrv_client_info: [' . print_r(sqlsrv_client_info($db_conn), true) . ']';

    /*
     * symptoms:
     * - when trying to open a transaction, this error occurs:
     * "New transaction is not allowed because there are other threads running in the session."
     * even though the resultset was fetched entirely!
     *
     * required column properties for physical tables:
     *  - contains at least one NULL value
     *  - column has no index
     */
    $query = <<<SQL
        SELECT COUNT(*) AS num_records FROM
        (
            SELECT  MIN(foo.bar) AS baz
            FROM  
            (
                SELECT NULL AS bar
                
                  UNION
                  
                SELECT 'bar' AS bar
            ) foo
            
            UNION
            
            SELECT  NULL AS bar
        ) foobar
SQL;
    
    $ps = sqlsrv_prepare($db_conn, $query, array(), array('Scrollable' => SQLSRV_CURSOR_FORWARD));
    if (!$ps) {
        throw new Exception('no ps');
    }
    if (!sqlsrv_execute($ps)) {
        throw new Exception('execute failed');
    }
    
    $result = sqlsrv_fetch_array($ps);
    var_dump($result);
    
    // uncomment to workaround the unexpected error below:
    //$result = sqlsrv_fetch_array($ps);
    //var_dump($result);
    
    // this fails but should not fail
    if (!sqlsrv_begin_transaction($db_conn)) {
        throw new Exception(print_r(sqlsrv_errors(), true));
    }
    
} catch (Exception $e) {
    var_dump($e);
}

function get_db_conn_sqlsrv()
{
    $host = "127.0.0.1\SQLExpress,1433";
    $conn_info = array(
        'Database'  => '[to_be_replaced]',
        'MultipleActiveResultSets'  => true,
        'CharacterSet' => 'UTF-8',
        'UID' => '[to_be_replaced]',
        'PWD' => '[to_be_replaced]'
        );

    sqlsrv_configure('WarningsReturnAsErrors', 0);
    $conn = sqlsrv_connect($host, $conn_info);
    if (!$conn) {
        throw new Exception('no link');
    }

    return $conn;
}
###################################################################

Expected result: no error when calling sqlsrv_begin_transaction().
Actual result: "New transaction is not allowed because there are other threads running in the session."

php version: [7.0.15]
sqlsrv_client_info: [
(
    [DriverDllName] => msodbcsql11.dll
    [DriverODBCVer] => 03.80
    [DriverVer] => 12.00.5579
    [ExtensionVer] => 4.1.8930.1
)

Best regards
Lars

Viewing all articles
Browse latest Browse all 391

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>