@@ -544,11 +544,11 @@ function with_transaction(Session $session, callable $callback, array $transacti
544
544
*/
545
545
function extract_session_from_options (array $ options ): ?Session
546
546
{
547
- if (! isset ($ options ['session ' ]) || ! $ options ['session ' ] instanceof Session) {
548
- return null ;
547
+ if (isset ($ options ['session ' ]) && $ options ['session ' ] instanceof Session) {
548
+ $ options [ ' session ' ] ;
549
549
}
550
550
551
- return $ options [ ' session ' ] ;
551
+ return null ;
552
552
}
553
553
554
554
/**
@@ -558,33 +558,43 @@ function extract_session_from_options(array $options): ?Session
558
558
*/
559
559
function extract_read_preference_from_options (array $ options ): ?ReadPreference
560
560
{
561
- if (! isset ($ options ['readPreference ' ]) || ! $ options ['readPreference ' ] instanceof ReadPreference) {
562
- return null ;
561
+ if (isset ($ options ['readPreference ' ]) && $ options ['readPreference ' ] instanceof ReadPreference) {
562
+ return $ options [ ' readPreference ' ] ;
563
563
}
564
564
565
- return $ options [ ' readPreference ' ] ;
565
+ return null ;
566
566
}
567
567
568
568
/**
569
- * Performs server selection, respecting the readPreference and session options
570
- * (if given)
569
+ * Performs server selection, respecting the readPreference and session options.
570
+ *
571
+ * The pinned server for an active transaction takes priority, followed by an
572
+ * operation-level read preference, followed by an active transaction's read
573
+ * preference, followed by a primary read preference.
571
574
*
572
575
* @internal
573
576
*/
574
577
function select_server (Manager $ manager , array $ options ): Server
575
578
{
576
579
$ session = extract_session_from_options ($ options );
577
580
$ server = $ session instanceof Session ? $ session ->getServer () : null ;
581
+
582
+ // Pinned server for an active transaction takes priority
578
583
if ($ server !== null ) {
579
584
return $ server ;
580
585
}
581
586
587
+ // Operation read preference takes priority
582
588
$ readPreference = extract_read_preference_from_options ($ options );
583
- if (! $ readPreference instanceof ReadPreference) {
584
- // TODO: PHPLIB-476: Read transaction read preference once PHPC-1439 is implemented
585
- $ readPreference = new ReadPreference (ReadPreference::PRIMARY );
589
+
590
+ // Read preference for an active transaction takes priority
591
+ if ($ readPreference === null && $ session instanceof Session && $ session ->isInTransaction ()) {
592
+ /* Session::getTransactionOptions() should always return an array if the
593
+ * session is in a transaction, but we can be defensive. */
594
+ $ readPreference = extract_read_preference_from_options ($ session ->getTransactionOptions () ?? []);
586
595
}
587
596
597
+ // Manager::selectServer() defaults to a primary read preference
588
598
return $ manager ->selectServer ($ readPreference );
589
599
}
590
600
0 commit comments