@@ -2378,6 +2378,99 @@ function (Transaction $t) use ($sql) {
23782378 );
23792379 }
23802380
2381+ public function testRunTransactionWithClientLevelIsolationLevel ()
2382+ {
2383+ $ sql = 'SELECT example FROM sql_query ' ;
2384+ $ stream = $ this ->prophesize (ServerStream::class);
2385+ $ stream ->readAll ()
2386+ ->shouldBeCalledOnce ()
2387+ ->willReturn ([new ResultSet (['stats ' => new ResultSetStats (['row_count_exact ' => 0 ])])]);
2388+
2389+ $ this ->spannerClient ->executeStreamingSql (
2390+ Argument::that (function (ExecuteSqlRequest $ request ) {
2391+ $ txnOptions = $ request ->getTransaction ()->getBegin ();
2392+ $ this ->assertNotNull ($ txnOptions );
2393+ $ this ->assertEquals (IsolationLevel::SERIALIZABLE , $ txnOptions ->getIsolationLevel ());
2394+ return true ;
2395+ }),
2396+ Argument::type ('array ' )
2397+ )
2398+ ->shouldBeCalledOnce ()
2399+ ->willReturn ($ stream ->reveal ());
2400+
2401+ $ session = $ this ->prophesize (SessionCache::class);
2402+ $ session ->name ()->willReturn ($ this ->sessionName );
2403+
2404+ $ database = new Database (
2405+ $ this ->spannerClient ->reveal (),
2406+ $ this ->databaseAdminClient ->reveal (),
2407+ $ this ->serializer ,
2408+ $ this ->instance ,
2409+ self ::PROJECT ,
2410+ self ::DATABASE ,
2411+ $ session ->reveal (),
2412+ ['isolationLevel ' => IsolationLevel::SERIALIZABLE ]
2413+ );
2414+
2415+ $ database ->runTransaction (
2416+ function (Transaction $ t ) use ($ sql ) {
2417+ // Run a fake query
2418+ $ t ->executeUpdate ($ sql );
2419+
2420+ // Simulate calling Transaction::commmit()
2421+ $ prop = new \ReflectionProperty ($ t , 'state ' );
2422+ $ prop ->setValue ($ t , Transaction::STATE_COMMITTED );
2423+ }
2424+ );
2425+ }
2426+
2427+ public function testRunTransactionWithClientLevelIsolationLevelOverride ()
2428+ {
2429+ $ sql = 'SELECT example FROM sql_query ' ;
2430+ $ stream = $ this ->prophesize (ServerStream::class);
2431+ $ stream ->readAll ()
2432+ ->shouldBeCalledOnce ()
2433+ ->willReturn ([new ResultSet (['stats ' => new ResultSetStats (['row_count_exact ' => 0 ])])]);
2434+
2435+ $ this ->spannerClient ->executeStreamingSql (
2436+ Argument::that (function (ExecuteSqlRequest $ request ) {
2437+ $ txnOptions = $ request ->getTransaction ()->getBegin ();
2438+ $ this ->assertNotNull ($ txnOptions );
2439+ $ this ->assertEquals (IsolationLevel::REPEATABLE_READ , $ txnOptions ->getIsolationLevel ());
2440+ return true ;
2441+ }),
2442+ Argument::type ('array ' )
2443+ )
2444+ ->shouldBeCalledOnce ()
2445+ ->willReturn ($ stream ->reveal ());
2446+
2447+ $ session = $ this ->prophesize (SessionCache::class);
2448+ $ session ->name ()->willReturn ($ this ->sessionName );
2449+
2450+ $ database = new Database (
2451+ $ this ->spannerClient ->reveal (),
2452+ $ this ->databaseAdminClient ->reveal (),
2453+ $ this ->serializer ,
2454+ $ this ->instance ,
2455+ self ::PROJECT ,
2456+ self ::DATABASE ,
2457+ $ session ->reveal (),
2458+ ['isolationLevel ' => IsolationLevel::SERIALIZABLE ]
2459+ );
2460+
2461+ $ database ->runTransaction (
2462+ function (Transaction $ t ) use ($ sql ) {
2463+ // Run a fake query
2464+ $ t ->executeUpdate ($ sql );
2465+
2466+ // Simulate calling Transaction::commmit()
2467+ $ prop = new \ReflectionProperty ($ t , 'state ' );
2468+ $ prop ->setValue ($ t , Transaction::STATE_COMMITTED );
2469+ },
2470+ ['transactionOptions ' => ['isolationLevel ' => IsolationLevel::REPEATABLE_READ ]]
2471+ );
2472+ }
2473+
23812474 public function testRunTransactionWithReadLockMode ()
23822475 {
23832476 $ sql = 'SELECT example FROM sql_query ' ;
@@ -2415,6 +2508,101 @@ function (Transaction $t) use ($sql) {
24152508 );
24162509 }
24172510
2511+ public function testRunTransactionWithClientLevelReadLockMode ()
2512+ {
2513+ $ sql = 'SELECT example FROM sql_query ' ;
2514+ $ stream = $ this ->prophesize (ServerStream::class);
2515+ $ stream ->readAll ()
2516+ ->shouldBeCalledOnce ()
2517+ ->willReturn ([new ResultSet (['stats ' => new ResultSetStats (['row_count_exact ' => 0 ])])]);
2518+
2519+ $ this ->spannerClient ->executeStreamingSql (
2520+ Argument::that (function (ExecuteSqlRequest $ request ) {
2521+ $ txnOptions = $ request ->getTransaction ()->getBegin ();
2522+ $ this ->assertNotNull ($ txnOptions );
2523+ $ this ->assertNotNull ($ readWriteTxnOptions = $ txnOptions ->getReadWrite ());
2524+ $ this ->assertEquals (ReadLockMode::PESSIMISTIC , $ readWriteTxnOptions ->getReadLockMode ());
2525+ return true ;
2526+ }),
2527+ Argument::type ('array ' )
2528+ )
2529+ ->shouldBeCalledOnce ()
2530+ ->willReturn ($ stream ->reveal ());
2531+
2532+ $ session = $ this ->prophesize (SessionCache::class);
2533+ $ session ->name ()->willReturn ($ this ->sessionName );
2534+
2535+ $ database = new Database (
2536+ $ this ->spannerClient ->reveal (),
2537+ $ this ->databaseAdminClient ->reveal (),
2538+ $ this ->serializer ,
2539+ $ this ->instance ,
2540+ self ::PROJECT ,
2541+ self ::DATABASE ,
2542+ $ session ->reveal (),
2543+ ['readLockMode ' => ReadLockMode::PESSIMISTIC ]
2544+ );
2545+
2546+ $ database ->runTransaction (
2547+ function (Transaction $ t ) use ($ sql ) {
2548+ // Run a fake query
2549+ $ t ->executeUpdate ($ sql );
2550+
2551+ // Simulate calling Transaction::commmit()
2552+ $ prop = new \ReflectionProperty ($ t , 'state ' );
2553+ $ prop ->setValue ($ t , Transaction::STATE_COMMITTED );
2554+ }
2555+ );
2556+ }
2557+
2558+ public function testRunTransactionWithClientLevelReadLockModeOverride ()
2559+ {
2560+ $ sql = 'SELECT example FROM sql_query ' ;
2561+ $ stream = $ this ->prophesize (ServerStream::class);
2562+ $ stream ->readAll ()
2563+ ->shouldBeCalledOnce ()
2564+ ->willReturn ([new ResultSet (['stats ' => new ResultSetStats (['row_count_exact ' => 0 ])])]);
2565+
2566+ $ this ->spannerClient ->executeStreamingSql (
2567+ Argument::that (function (ExecuteSqlRequest $ request ) {
2568+ $ txnOptions = $ request ->getTransaction ()->getBegin ();
2569+ $ this ->assertNotNull ($ txnOptions );
2570+ $ this ->assertNotNull ($ readWriteTxnOptions = $ txnOptions ->getReadWrite ());
2571+ $ this ->assertEquals (ReadLockMode::OPTIMISTIC , $ readWriteTxnOptions ->getReadLockMode ());
2572+ return true ;
2573+ }),
2574+ Argument::type ('array ' )
2575+ )
2576+ ->shouldBeCalledOnce ()
2577+ ->willReturn ($ stream ->reveal ());
2578+
2579+ $ session = $ this ->prophesize (SessionCache::class);
2580+ $ session ->name ()->willReturn ($ this ->sessionName );
2581+
2582+ $ database = new Database (
2583+ $ this ->spannerClient ->reveal (),
2584+ $ this ->databaseAdminClient ->reveal (),
2585+ $ this ->serializer ,
2586+ $ this ->instance ,
2587+ self ::PROJECT ,
2588+ self ::DATABASE ,
2589+ $ session ->reveal (),
2590+ ['readLockMode ' => ReadLockMode::PESSIMISTIC ]
2591+ );
2592+
2593+ $ database ->runTransaction (
2594+ function (Transaction $ t ) use ($ sql ) {
2595+ // Run a fake query
2596+ $ t ->executeUpdate ($ sql );
2597+
2598+ // Simulate calling Transaction::commmit()
2599+ $ prop = new \ReflectionProperty ($ t , 'state ' );
2600+ $ prop ->setValue ($ t , Transaction::STATE_COMMITTED );
2601+ },
2602+ ['transactionOptions ' => ['readLockMode ' => ReadLockMode::OPTIMISTIC ]]
2603+ );
2604+ }
2605+
24182606 public function testTransactionWithReadLockMode ()
24192607 {
24202608 $ this ->spannerClient ->beginTransaction (
0 commit comments