Files
huntingclubroster/classes/DatabaseTransaction.php
T

20 lines
925 B
PHP
Raw Normal View History

<?php
/** Retry only complete, rollback-safe database work; never put email delivery here. */
final class DatabaseTransaction {
public static function run(PDO $db,callable $work): mixed {
if($db->inTransaction())throw new LogicException('Retryable work must own its transaction.');
for($attempt=1;$attempt<=3;$attempt++){
$db->beginTransaction();
try{
$result=$work($db);$db->commit();return $result;
}catch(Throwable $error){
if($db->inTransaction())$db->rollBack();
$retryable=$error instanceof PDOException && (in_array((int)($error->errorInfo[1]??0),[1205,1213],true)||$error->getCode()==='40001');
if(!$retryable||$attempt===3)throw $error;
usleep(random_int(10000,30000)*$attempt);
}
}
throw new LogicException('Transaction attempts exhausted.');
}
}