4
4
use Jenssegers \Mongodb \Connection ;
5
5
use Jenssegers \Mongodb \Eloquent \Model ;
6
6
use MongoDB \BSON \ObjectId ;
7
+ use MongoDB \Driver \Exception \BulkWriteException ;
7
8
use MongoDB \Driver \Server ;
8
9
9
10
class TransactionTest extends TestCase
@@ -317,6 +318,8 @@ public function testTransaction(): void
317
318
{
318
319
User::create (['name ' => 'klinson ' , 'age ' => 20 , 'title ' => 'admin ' ]);
319
320
321
+ // The $connection parameter may be unused, but is implicitly used to
322
+ // test that the closure is executed with the connection as an argument.
320
323
DB ::transaction (function (Connection $ connection ): void {
321
324
User::create (['name ' => 'alcaeus ' , 'age ' => 38 , 'title ' => 'admin ' ]);
322
325
User::where (['name ' => 'klinson ' ])->update (['age ' => 21 ]);
@@ -336,14 +339,18 @@ public function testTransactionRepeatsOnTransientFailure(): void
336
339
$ timesRun = 0 ;
337
340
338
341
DB ::transaction (function () use (&$ timesRun ): void {
339
- User::where (['name ' => 'klinson ' ])->update (['age ' => 21 ]);
342
+ $ timesRun ++;
343
+
344
+ // Run a query to start the transaction on the server
345
+ User::create (['name ' => 'alcaeus ' , 'age ' => 38 , 'title ' => 'admin ' ]);
340
346
341
- // Update user during transaction to simulate a simultaneous update
342
- if ($ timesRun == 0 ) {
347
+ // Update user outside of the session
348
+ if ($ timesRun == 1 ) {
343
349
DB ::getCollection ('users ' )->updateOne (['name ' => 'klinson ' ], ['$set ' => ['age ' => 22 ]]);
344
350
}
345
351
346
- $ timesRun ++;
352
+ // This update will create a write conflict, aborting the transaction
353
+ User::where (['name ' => 'klinson ' ])->update (['age ' => 21 ]);
347
354
}, 2 );
348
355
349
356
$ this ->assertSame (2 , $ timesRun );
@@ -356,14 +363,25 @@ public function testTransactionRespectsRepetitionLimit(): void
356
363
357
364
$ timesRun = 0 ;
358
365
359
- DB ::transaction (function () use (&$ timesRun ): void {
360
- User::where (['name ' => 'klinson ' ])->update (['age ' => 21 ]);
366
+ try {
367
+ DB ::transaction (function () use (&$ timesRun ): void {
368
+ $ timesRun ++;
361
369
362
- // Update user during transaction to simulate a simultaneous update
363
- DB :: getCollection ( ' users ' )-> updateOne ( ['name ' => 'klinson ' ], [ ' $inc ' => [ ' age ' => 2 ] ]);
370
+ // Run a query to start the transaction on the server
371
+ User:: create ( ['name ' => 'alcaeus ' , ' age ' => 38 , ' title ' => ' admin ' ]);
364
372
365
- $ timesRun ++;
366
- }, 2 );
373
+ // Update user outside of the session
374
+ DB ::getCollection ('users ' )->updateOne (['name ' => 'klinson ' ], ['$inc ' => ['age ' => 2 ]]);
375
+
376
+ // This update will create a write conflict, aborting the transaction
377
+ User::where (['name ' => 'klinson ' ])->update (['age ' => 21 ]);
378
+ }, 2 );
379
+
380
+ $ this ->fail ('Expected exception during transaction ' );
381
+ } catch (BulkWriteException $ e ) {
382
+ $ this ->assertInstanceOf (BulkWriteException::class, $ e );
383
+ $ this ->assertStringContainsString ('WriteConflict ' , $ e ->getMessage ());
384
+ }
367
385
368
386
$ this ->assertSame (2 , $ timesRun );
369
387
0 commit comments