@@ -15,6 +15,13 @@ class Pool extends Adapter
1515 */
1616 protected UtopiaPool $ pool ;
1717
18+ /**
19+ * This is used to keep the same adapter instance during a transaction.
20+ *
21+ * @var Adapter|null
22+ */
23+ private ?Adapter $ pinned = null ;
24+
1825 /**
1926 * @param UtopiaPool<covariant Adapter> $pool The pool to use for connections. Must contain instances of Adapter.
2027 * @throws DatabaseException
@@ -60,7 +67,7 @@ public function __construct(UtopiaPool $pool)
6067 */
6168 public function delegate (string $ method , array $ args ): mixed
6269 {
63- return $ this -> pool -> use ( function (Adapter $ adapter ) use ( $ method , $ args ) {
70+ $ configure = function (Adapter $ adapter ): Adapter {
6471 // Run setters in case config changed since this connection was last used
6572 $ adapter ->setDatabase ($ this ->getDatabase ());
6673 $ adapter ->setNamespace ($ this ->getNamespace ());
@@ -79,7 +86,24 @@ public function delegate(string $method, array $args): mixed
7986 $ adapter ->setMetadata ($ key , $ value );
8087 }
8188
82- return $ adapter ->{$ method }(...$ args );
89+ return $ adapter ;
90+ };
91+
92+ if (!empty ($ this ->pinned )) {
93+ // If a pinned adapter is set, use it directly
94+ $ pinned = $ this ->pinned ;
95+ if ($ method === 'commitTransaction ' || $ method === 'rollbackTransaction ' ) {
96+ // If we are finish a transaction, reset the pinned adapter
97+ $ this ->pinned = null ;
98+ }
99+ return $ configure ($ pinned )->{$ method }(...$ args );
100+ }
101+
102+ return $ this ->pool ->use (function (Adapter $ adapter ) use ($ method , $ args , $ configure ) {
103+ if ($ method === 'startTransaction ' && $ this ->pinned === null ) {
104+ $ this ->pinned = $ adapter ;
105+ }
106+ return $ configure ($ adapter )->{$ method }(...$ args );
83107 });
84108 }
85109
0 commit comments