@@ -92,6 +92,9 @@ class Connection extends PrimaryReadReplicaConnection {
9292 /** @var array<string, int> */
9393 protected $ tableDirtyWrites = [];
9494
95+ protected bool $ logDbException = false ;
96+ private ?array $ transactionBacktrace = null ;
97+
9598 protected bool $ logRequestId ;
9699 protected string $ requestId ;
97100
@@ -124,6 +127,7 @@ public function __construct(
124127 $ this ->logger = \OC ::$ server ->get (LoggerInterface::class);
125128
126129 $ this ->logRequestId = $ this ->systemConfig ->getValue ('db.log_request_id ' , false );
130+ $ this ->logDbException = $ this ->systemConfig ->getValue ('db.log_exceptions ' , false );
127131 $ this ->requestId = Server::get (IRequestId::class)->getId ();
128132
129133 /** @var \OCP\Profiler\IProfiler */
@@ -325,7 +329,12 @@ public function executeQuery(string $sql, array $params = [], $types = [], ?Quer
325329 $ sql = $ this ->finishQuery ($ sql );
326330 $ this ->queriesExecuted ++;
327331 $ this ->logQueryToFile ($ sql );
328- return parent ::executeQuery ($ sql , $ params , $ types , $ qcp );
332+ try {
333+ return parent ::executeQuery ($ sql , $ params , $ types , $ qcp );
334+ } catch (\Exception $ e ) {
335+ $ this ->logDatabaseException ($ e );
336+ throw $ e ;
337+ }
329338 }
330339
331340 /**
@@ -370,7 +379,12 @@ public function executeStatement($sql, array $params = [], array $types = []): i
370379 $ sql = $ this ->finishQuery ($ sql );
371380 $ this ->queriesExecuted ++;
372381 $ this ->logQueryToFile ($ sql );
373- return (int )parent ::executeStatement ($ sql , $ params , $ types );
382+ try {
383+ return (int )parent ::executeStatement ($ sql , $ params , $ types );
384+ } catch (\Exception $ e ) {
385+ $ this ->logDatabaseException ($ e );
386+ throw $ e ;
387+ }
374388 }
375389
376390 protected function logQueryToFile (string $ sql ): void {
@@ -437,11 +451,21 @@ public function realLastInsertId($seqName = null) {
437451 * @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
438452 */
439453 public function insertIfNotExist ($ table , $ input , ?array $ compare = null ) {
440- return $ this ->adapter ->insertIfNotExist ($ table , $ input , $ compare );
454+ try {
455+ return $ this ->adapter ->insertIfNotExist ($ table , $ input , $ compare );
456+ } catch (\Exception $ e ) {
457+ $ this ->logDatabaseException ($ e );
458+ throw $ e ;
459+ }
441460 }
442461
443462 public function insertIgnoreConflict (string $ table , array $ values ) : int {
444- return $ this ->adapter ->insertIgnoreConflict ($ table , $ values );
463+ try {
464+ return $ this ->adapter ->insertIgnoreConflict ($ table , $ values );
465+ } catch (\Exception $ e ) {
466+ $ this ->logDatabaseException ($ e );
467+ throw $ e ;
468+ }
445469 }
446470
447471 private function getType ($ value ) {
@@ -700,6 +724,7 @@ private function getMigrator() {
700724
701725 public function beginTransaction () {
702726 if (!$ this ->inTransaction ()) {
727+ $ this ->transactionBacktrace = debug_backtrace (DEBUG_BACKTRACE_IGNORE_ARGS );
703728 $ this ->transactionActiveSince = microtime (true );
704729 }
705730 return parent ::beginTransaction ();
@@ -709,6 +734,7 @@ public function commit() {
709734 $ result = parent ::commit ();
710735 if ($ this ->getTransactionNestingLevel () === 0 ) {
711736 $ timeTook = microtime (true ) - $ this ->transactionActiveSince ;
737+ $ this ->transactionBacktrace = null ;
712738 $ this ->transactionActiveSince = null ;
713739 if ($ timeTook > 1 ) {
714740 $ this ->logger ->debug ('Transaction took ' . $ timeTook . 's ' , ['exception ' => new \Exception ('Transaction took ' . $ timeTook . 's ' )]);
@@ -721,6 +747,7 @@ public function rollBack() {
721747 $ result = parent ::rollBack ();
722748 if ($ this ->getTransactionNestingLevel () === 0 ) {
723749 $ timeTook = microtime (true ) - $ this ->transactionActiveSince ;
750+ $ this ->transactionBacktrace = null ;
724751 $ this ->transactionActiveSince = null ;
725752 if ($ timeTook > 1 ) {
726753 $ this ->logger ->debug ('Transaction rollback took longer than 1s: ' . $ timeTook , ['exception ' => new \Exception ('Long running transaction rollback ' )]);
0 commit comments