9
9
use Doctrine \DBAL \Cache \QueryCacheProfile ;
10
10
use Doctrine \DBAL \Driver \API \ExceptionConverter ;
11
11
use Doctrine \DBAL \Driver \Connection as DriverConnection ;
12
+ use Doctrine \DBAL \Driver \Exception as TheDriverException ;
12
13
use Doctrine \DBAL \Driver \ServerInfoAwareConnection ;
13
14
use Doctrine \DBAL \Driver \Statement as DriverStatement ;
14
15
use Doctrine \DBAL \Event \TransactionBeginEventArgs ;
15
16
use Doctrine \DBAL \Event \TransactionCommitEventArgs ;
16
17
use Doctrine \DBAL \Event \TransactionRollBackEventArgs ;
17
18
use Doctrine \DBAL \Exception \ConnectionLost ;
19
+ use Doctrine \DBAL \Exception \DeadlockException ;
18
20
use Doctrine \DBAL \Exception \DriverException ;
21
+ use Doctrine \DBAL \Exception \ForeignKeyConstraintViolationException ;
19
22
use Doctrine \DBAL \Exception \InvalidArgumentException ;
23
+ use Doctrine \DBAL \Exception \TransactionRolledBack ;
24
+ use Doctrine \DBAL \Exception \UniqueConstraintViolationException ;
20
25
use Doctrine \DBAL \Platforms \AbstractPlatform ;
21
26
use Doctrine \DBAL \Query \Expression \ExpressionBuilder ;
22
27
use Doctrine \DBAL \Query \QueryBuilder ;
@@ -1283,16 +1288,36 @@ public function transactional(Closure $func)
1283
1288
1284
1289
try {
1285
1290
$ res = $ func ($ this );
1286
- $ this ->commit ();
1287
1291
1288
1292
$ successful = true ;
1289
-
1290
- return $ res ;
1291
1293
} finally {
1292
1294
if (! $ successful ) {
1293
1295
$ this ->rollBack ();
1294
1296
}
1295
1297
}
1298
+
1299
+ $ shouldRollback = true ;
1300
+ try {
1301
+ $ this ->commit ();
1302
+
1303
+ $ shouldRollback = false ;
1304
+ } catch (TheDriverException $ t ) {
1305
+ $ convertedException = $ this ->handleDriverException ($ t , null );
1306
+ $ shouldRollback = ! (
1307
+ $ convertedException instanceof TransactionRolledBack
1308
+ || $ convertedException instanceof UniqueConstraintViolationException
1309
+ || $ convertedException instanceof ForeignKeyConstraintViolationException
1310
+ || $ convertedException instanceof DeadlockException
1311
+ );
1312
+
1313
+ throw $ t ;
1314
+ } finally {
1315
+ if ($ shouldRollback ) {
1316
+ $ this ->rollBack ();
1317
+ }
1318
+ }
1319
+
1320
+ return $ res ;
1296
1321
}
1297
1322
1298
1323
/**
@@ -1424,12 +1449,21 @@ public function commit()
1424
1449
1425
1450
$ connection = $ this ->getWrappedConnection ();
1426
1451
1427
- if ($ this ->transactionNestingLevel === 1 ) {
1428
- $ result = $ this ->doCommit ($ connection );
1429
- } elseif ($ this ->nestTransactionsWithSavepoints ) {
1430
- $ this ->releaseSavepoint ($ this ->_getNestedTransactionSavePointName ());
1452
+ try {
1453
+ if ($ this ->transactionNestingLevel === 1 ) {
1454
+ $ result = $ this ->doCommit ($ connection );
1455
+ } elseif ($ this ->nestTransactionsWithSavepoints ) {
1456
+ $ this ->releaseSavepoint ($ this ->_getNestedTransactionSavePointName ());
1457
+ }
1458
+ } finally {
1459
+ $ this ->updateTransactionStateAfterCommit ();
1431
1460
}
1432
1461
1462
+ return $ result ;
1463
+ }
1464
+
1465
+ private function updateTransactionStateAfterCommit (): void
1466
+ {
1433
1467
--$ this ->transactionNestingLevel ;
1434
1468
1435
1469
$ eventManager = $ this ->getEventManager ();
@@ -1446,12 +1480,10 @@ public function commit()
1446
1480
}
1447
1481
1448
1482
if ($ this ->autoCommit !== false || $ this ->transactionNestingLevel !== 0 ) {
1449
- return $ result ;
1483
+ return ;
1450
1484
}
1451
1485
1452
1486
$ this ->beginTransaction ();
1453
-
1454
- return $ result ;
1455
1487
}
1456
1488
1457
1489
/**
0 commit comments