File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -38,11 +38,18 @@ public function startTransaction(): bool
3838 {
3939 try {
4040 if ($ this ->inTransaction === 0 ) {
41- if ($ this ->getPDO ()->inTransaction ()) {
42- $ this ->getPDO ()->rollBack ();
43- } else {
44- // If no active transaction, this has no effect.
45- $ this ->getPDO ()->prepare ('ROLLBACK ' )->execute ();
41+ try {
42+ if ($ this ->getPDO ()->inTransaction ()) {
43+ $ this ->getPDO ()->rollBack ();
44+ } else {
45+ // If no active transaction, this has no effect.
46+ $ this ->getPDO ()->prepare ('ROLLBACK ' )->execute ();
47+ }
48+ } catch (PDOException ) {
49+ // A pooled connection can report a transaction it no longer
50+ // holds after a reconnect (e.g. Swoole PDOProxy keeps its own
51+ // counter), making this cleanup rollback throw. It is best
52+ // effort; swallow it and begin a fresh transaction below.
4653 }
4754
4855 $ result = $ this ->getPDO ()->beginTransaction ();
Original file line number Diff line number Diff line change 55use PDOException ;
66use PHPUnit \Framework \TestCase ;
77use Utopia \Database \Adapter \MySQL ;
8+ use Utopia \Database \Adapter \Postgres ;
89use Utopia \Database \Exception \Transaction as TransactionException ;
910
1011class SQLTransactionTest extends TestCase
@@ -57,4 +58,24 @@ public function testStartTransactionDoesNotMaskBeginFailureAfterDesyncedRollback
5758
5859 $ adapter ->startTransaction ();
5960 }
61+
62+ public function testPostgresStartTransactionRecoversFromDesyncedRollback (): void
63+ {
64+ $ pdo = $ this ->getMockBuilder (\PDO ::class)
65+ ->disableOriginalConstructor ()
66+ ->getMock ();
67+
68+ $ pdo ->method ('inTransaction ' )->willReturn (true );
69+ $ pdo ->method ('rollBack ' )->willThrowException (
70+ new PDOException ('There is no active transaction ' )
71+ );
72+ $ pdo ->expects ($ this ->once ())
73+ ->method ('beginTransaction ' )
74+ ->willReturn (true );
75+
76+ $ adapter = new Postgres ($ pdo );
77+
78+ $ this ->assertTrue ($ adapter ->startTransaction ());
79+ $ this ->assertTrue ($ adapter ->inTransaction ());
80+ }
6081}
You can’t perform that action at this time.
0 commit comments