8000 Allow reconnect in transaction by setting transactions to 0 (#15931) · laravel/framework@01f350e · GitHub
[go: up one dir, main page]

Skip to content

Commit 01f350e

Browse files
halaeitaylorotwell
authored andcommitted
Allow reconnect in transaction by setting transactions to 0 (#15931)
1 parent 6f21736 commit 01f350e

File tree

2 files changed

+33
-20
lines changed

2 files changed

+33
-20
lines changed

src/Illuminate/Database/Connection.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use Exception;
88
use Throwable;
99
use LogicException;
10-
use RuntimeException;
1110
use DateTimeInterface;
1211
use Illuminate\Support\Arr;
1312
use Illuminate\Database\Query\Expression;
@@ -985,14 +984,10 @@ public function getReadPdo()
985984
*
986985
* @param \PDO|null $pdo
987986
* @return $this
988-
*
989-
* @throws \RuntimeException
990987
*/
991988
public function setPdo($pdo)
992989
{
993-
if ($this->transactions >= 1) {
994-
throw new RuntimeException("Can't swap PDO instance while within transaction.");
995-
}
990+
$this->transactions = 0;
996991

997992
$this->pdo = $pdo;
998993

tests/Database/DatabaseConnectionTest.php

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,14 @@ public function testBeginTransactionMethodNeverRetriesIfWithinTransaction()
156156
}
157157
}
158158

159-
public function testCantSwapPDOWithOpenTransaction()
159+
public function testSwapPDOWithOpenTransactionResetsTransactionLevel()
160160
{
161161
$pdo = $this->createMock('DatabaseConnectionTestMockPDO');
162162
$pdo->expects($this->once())->method('beginTransaction')->will($this->returnValue(true));
163163
$connection = $this->getMockConnection([], $pdo);
164164
$connection->beginTransaction();
165-
$this->setExpectedException('RuntimeException', "Can't swap PDO instance while within transaction.");
166165
$connection->disconnect();
166+
$this->assertEquals(0, $connection->transactionLevel());
167167
}
168168

169169
public function testBeganTransactionFiresEventsIfSet()
@@ -240,24 +240,42 @@ public function testTransactionMethodRollsbackAndThrows()
240240
}
241241

242242
/**
243-
* @expectedException RuntimeException
243+
* @expectedException \Illuminate\Database\QueryException
244244
*/
245-
public function testTransactionMethodDisallowPDOChanging()
245+
public function testOnLostConnectionPDOIsNotSwappedWithinATransaction()
246246
{
247-
$pdo = $this->getMockBuilder('DatabaseConnectionTestMockPDO')->setMethods(['beginTransaction', 'commit', 'rollBack'])->getMock();
248-
$pdo->expects($this->once())->method('beginTransaction');
249-
$pdo->expects($this->once())->method('rollBack');
250-
$pdo->expects($this->never())->method('commit');
247+
$pdo = m::mock(PDO::class);
248+
$pdo->shouldReceive('beginTransaction')->once();
249+
$statement = m::mock(PDOStatement::class);
250+
$pdo->shouldReceive('prepare')->once()->andReturn($statement);
251+
$statement->shouldReceive('execute')->once()->andThrow(new PDOException('server has gone away'));
251252

252-
$mock = $this->getMockConnection([], $pdo);
253+
$connection = new \Illuminate\Database\Connection($pdo);
254+
$connection->beginTransaction();
255+
$connection->statement('foo');
256+
}
253257

254-
$mock->setReconnector(function ($connection) {
255-
$connection->setPDO(null);
256-
});
258+
public function testOnLostConnectionPDOIsSwappedOutsideTransaction()
259+
{
260+
$pdo = m::mock(PDO::class);
261+
262+
$statement = m::mock(PDOStatement::class);
263+
$statement->shouldReceive('execute')->once()->andThrow(new PDOException('server has gone away'));
264+
$statement->shouldReceive('execute')->once()->andReturn('result');
265+
266+
$pdo->shouldReceive('prepare')->twice()->andReturn($statement);
257267

258-
$mock->transaction(function ($connection) {
259-
$connection->reconnect();
< 87D7 /code>
268+
$connection = new \Illuminate\Database\Connection($pdo);
269+
270+
$called = false;
271+
272+
$connection->setReconnector(function ($connection) use (&$called) {
273+
$called = true;
260274
});
275+
276+
$this->assertEquals('result', $connection->statement('foo'));
277+
278+
$this->assertTrue($called);
261279
}
262280

263281
public function testRunMethodRetriesOnFailure()

0 commit comments

Comments
 (0)
0