@@ -76,7 +76,7 @@ abstract class Driver implements DriverInterface, LoggerAwareInterface
76
76
protected $ pdo ;
77
77
78
78
/** @var int */
79
- protected $ transactionLevel ;
79
+ protected $ transactionLevel = 0 ;
80
80
81
81
/** @var HandlerInterface */
82
82
protected $ schemaHandler ;
@@ -102,7 +102,6 @@ public function __construct(
102
102
CompilerInterface $ queryCompiler ,
103
103
BuilderInterface $ queryBuilder
104
104
) {
105
- $ this ->transactionLevel = 0 ;
106
105
$ this ->schemaHandler = $ schemaHandler ->withDriver ($ this );
107
106
$ this ->queryBuilder = $ queryBuilder ->withDriver ($ this );
108
107
$ this ->queryCompiler = $ queryCompiler ;
@@ -352,7 +351,7 @@ public function lastInsertID(string $sequence = null)
352
351
*/
353
352
public function beginTransaction (string $ isolationLevel = null ): bool
354
353
{
355
- $ this ->transactionLevel ++ ;
354
+ ++ $ this ->transactionLevel ;
356
355
357
356
if ($ this ->transactionLevel === 1 ) {
358
357
if ($ isolationLevel !== null ) {
@@ -377,10 +376,11 @@ public function beginTransaction(string $isolationLevel = null): bool
377
376
try {
378
377
return $ this ->getPDO ()->beginTransaction ();
379
378
} catch (Throwable $ e ) {
379
+ $ this ->transactionLevel = 0 ;
380
380
throw $ this ->mapException ($ e , 'BEGIN TRANSACTION ' );
381
381
}
382
382
} else {
383
- $ this ->transactionLevel -- ;
383
+ $ this ->transactionLevel = 0 ;
384
384
throw $ e ;
385
385
}
386
386
}
@@ -395,10 +395,31 @@ public function beginTransaction(string $isolationLevel = null): bool
395
395
* Commit the active database transaction.
396
396
*
397
397
* @return bool
398
+ *
399
+ * @throws StatementException
398
400
*/
399
401
public function commitTransaction (): bool
400
402
{
401
- $ this ->transactionLevel --;
403
+ // Check active transaction
404
+ if (!$ this ->getPDO ()->inTransaction ()) {
405
+ if ($ this ->logger !== null ) {
406
+ $ this ->logger ->warning (
407
+ sprintf (
408
+ 'Attempt to commit a transaction that has not yet begun. Transaction level: %d ' ,
409
+ $ this ->transactionLevel
410
+ )
411
+ );
412
+ }
413
+
414
+ if ($ this ->transactionLevel === 0 ) {
415
+ return false ;
416
+ }
417
+
418
+ $ this ->transactionLevel = 0 ;
419
+ return true ;
420
+ }
421
+
422
+ --$ this ->transactionLevel ;
402
423
403
424
if ($ this ->transactionLevel === 0 ) {
404
425
if ($ this ->logger !== null ) {
@@ -421,10 +442,27 @@ public function commitTransaction(): bool
421
442
* Rollback the active database transaction.
422
443
*
423
444
* @return bool
445
+ *
446
+ * @throws StatementException
424
447
*/
425
448
public function rollbackTransaction (): bool
426
449
{
427
- $ this ->transactionLevel --;
450
+ // Check active transaction
451
+ if (!$ this ->getPDO ()->inTransaction ()) {
452
+ if ($ this ->logger !== null ) {
453
+ $ this ->logger ->warning (
454
+ sprintf (
455
+ 'Attempt to rollback a transaction that has not yet begun. Transaction level: %d ' ,
456
+ $ this ->transactionLevel
457
+ )
458
+ );
459
+ }
460
+
461
+ $ this ->transactionLevel = 0 ;
462
+ return false ;
463
+ }
464
+
465
+ --$ this ->transactionLevel ;
428
466
429
467
if ($ this ->transactionLevel === 0 ) {
430
468
if ($ this ->logger !== null ) {
0 commit comments