Skip to content

Commit 81e71e8

Browse files
committed
Merge branch 'master' into develop
2 parents e6e74d7 + c91edc7 commit 81e71e8

15 files changed

+3524
-122
lines changed

.github/workflows/ci.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
branches: [ master ]
6+
7+
jobs:
8+
phpunit:
9+
name: PHPUnit
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
php: [8.2]
14+
steps:
15+
- name: Checkout repository
16+
uses: actions/checkout@v4
17+
18+
- name: Setup PHP
19+
uses: shivammathur/setup-php@v2
20+
with:
21+
php-version: ${{ matrix.php }}
22+
coverage: none
23+
extensions: mbstring, pdo, pdo_sqlite, pdo_mysql
24+
25+
- name: Use composer cache
26+
uses: actions/cache@v4
27+
with:
28+
path: ~/.cache/composer
29+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
30+
restore-keys: |
31+
${{ runner.os }}-composer-
32+
33+
- name: Install dependencies
34+
run: composer install --no-progress --prefer-dist --no-interaction
35+
36+
- name: Run PHPUnit
37+
run: composer test
38+
39+
php-cs-fixer:
40+
name: PHP CS Fixer
41+
runs-on: ubuntu-latest
42+
strategy:
43+
matrix:
44+
php: [8.2]
45+
steps:
46+
- name: Checkout repository
47+
uses: actions/checkout@v4
48+
49+
- name: Setup PHP
50+
uses: shivammathur/setup-php@v2
51+
with:
52+
php-version: ${{ matrix.php }}
53+
extensions: mbstring, pdo
54+
55+
- name: Use composer cache
56+
uses: actions/cache@v4
57+
with:
58+
path: ~/.cache/composer
59+
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
60+
restore-keys: |
61+
${{ runner.os }}-composer-
62+
63+
- name: Install dependencies
64+
run: composer install --no-progress --prefer-dist --no-interaction
65+
66+
- name: Run PHP CS Fixer (dry-run)
67+
run: composer fix:ci

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
vendor/
33

44
.idea/
5+
.vscode/
6+
.DS_Store

.php-cs-fixer.cache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"php":"8.4.13","version":"3.88.2:v3.88.2#a8d15584bafb0f0d9d938827840060fd4a3ebc99","indent":" ","lineEnding":"\n","rules":{"binary_operator_spaces":{"default":"align_single_space_minimal"},"blank_line_after_opening_tag":true,"blank_line_between_import_groups":true,"blank_lines_before_namespace":true,"braces_position":{"allow_single_line_empty_anonymous_classes":true},"class_definition":{"inline_constructor_arguments":false,"space_before_parenthesis":true},"compact_nullable_type_declaration":true,"declare_equal_normalize":true,"lowercase_cast":true,"lowercase_static_reference":true,"modifier_keywords":true,"new_with_parentheses":{"anonymous_class":true},"no_blank_lines_after_class_opening":true,"no_extra_blank_lines":true,"no_leading_import_slash":true,"no_whitespace_in_blank_line":true,"ordered_class_elements":{"order":["use_trait"]},"ordered_imports":{"sort_algorithm":"alpha"},"return_type_declaration":true,"short_scalar_cast":true,"single_import_per_statement":{"group_to_single_imports":false},"single_space_around_construct":{"constructs_followed_by_a_single_space":["abstract","as","case","catch","class","const_import","do","else","elseif","final","finally","for","foreach","function","function_import","if","insteadof","interface","namespace","new","private","protected","public","static","switch","trait","try","use","use_lambda","while"],"constructs_preceded_by_a_single_space":["as","else","elseif","use_lambda"]},"single_trait_insert_per_statement":true,"ternary_operator_spaces":true,"unary_operator_spaces":{"only_dec_inc":true},"blank_line_after_namespace":true,"constant_case":true,"control_structure_braces":true,"control_structure_continuation_position":true,"elseif":true,"function_declaration":{"closure_fn_spacing":"one"},"indentation_type":true,"line_ending":true,"lowercase_keywords":true,"method_argument_space":{"after_heredoc":false,"attribute_placement":"ignore","on_multiline":"ensure_fully_multiline"},"no_break_comment":true,"no_closing_tag":true,"no_multiple_statements_per_line":true,"no_space_around_double_colon":true,"no_spaces_after_function_name":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":{"elements":["property"]},"single_line_after_imports":true,"spaces_inside_parentheses":true,"statement_indentation":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"encoding":true,"full_opening_tag":true,"array_syntax":{"syntax":"short"},"single_quote":true,"no_unused_imports":true,"no_superfluous_phpdoc_tags":true,"phpdoc_trim":true,"phpdoc_align":{"align":"left"},"blank_line_before_statement":{"statements":["return"]},"simplified_null_return":true,"void_return":true},"hashes":{"src\/RetryServiceProvider.php":"b6642465f4ed70477d21c0460e3677df","src\/DBTransactionRetryHelperOld.php":"358e3a95a390c013376e05cb0911b599","src\/DBTransactionRetryHelper.php":"3dfeb60b0234603d2046f39592b6a547","src\/Helper.php":"8ef8db53eed02278815b175b445a2ee9"}}

.php-cs-fixer.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
$finder = PhpCsFixer\Finder::create()
6+
->in([
7+
__DIR__ . '/src',
8+
])
9+
->name('*.php')
10+
->ignoreVCS(true);
11+
12+
return (new PhpCsFixer\Config())
13+
->setRiskyAllowed(true)
14+
->setRules([
15+
'@PSR12' => true,
16+
// 'declare_strict_types' => true,
17+
'no_extra_blank_lines' => true,
18+
'array_syntax' => ['syntax' => 'short'],
19+
'single_quote' => true,
20+
'no_unused_imports' => true,
21+
'ordered_imports' => ['sort_algorithm' => 'alpha'],
22+
'no_superfluous_phpdoc_tags' => true,
23+
'phpdoc_trim' => true,
24+
'phpdoc_align' => ['align' => 'left'],
25+
'binary_operator_spaces' => ['default' => 'align_single_space_minimal'],
26+
'blank_line_before_statement' => ['statements' => ['return']],
27+
'no_whitespace_in_blank_line' => true,
28+
'simplified_null_return' => true,
29+
'void_return' => true,
30+
])
31+
->setFinder($finder)
32+
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect());

README.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,36 @@ Features:
77
- Exponential backoff with jitter between attempts
88
- Structured logging per attempt to storage/logs
99
- Safe in HTTP, CLI and queue contexts (request info captured when available)
10+
- Transaction labeling for easier debugging
11+
- Enhanced logging with SQL query information
1012

1113
Installation:
12-
- Require the package via Composer and ensure Laravel auto-discovers the service provider (already configured).
14+
- Require the package via Composer: `composer require ahed92wakim/laravel-mysql-deadlock-retry`
1315

1416
Usage:
1517

16-
```
18+
```php
1719
use MysqlDeadlocks\RetryHelper\DBTransactionRetryHelper as Retry;
1820

1921
$result = Retry::transactionWithRetry(function () {
2022
// Your DB logic here (queries, models, etc.)
2123
// Return any value and it will be returned from transactionWithRetry
22-
}, maxRetries: 3, retryDelay: 2, logFileName: 'mysql-deadlocks-log');
24+
}, maxRetries: 3, retryDelay: 2, logFileName: 'mysql-deadlocks', trxLabel: 'user-update');
2325
```
2426

2527
Parameters:
2628
- maxRetries: number of attempts (default 3)
2729
- retryDelay: base delay in seconds; actual wait uses exponential backoff with jitter (default 2)
28-
- logFileName: file prefix under storage/logs/{today date} (default 'mysql-deadlocks.log')
30+
- logFileName: file prefix under storage/logs/{today date} (default 'database/mysql-deadlocks')
31+
- trxLabel: transaction label for easier identification in logs (default '')
32+
33+
Logging:
34+
- Logs are stored in storage/logs/{date}/ directory
35+
- Successful transactions after retries are logged as warnings
36+
- Failed transactions after all retries are logged as errors
37+
- Logs include SQL queries, stack traces, and request information when available
2938

3039
Notes:
3140
- Non-deadlock QueryException is thrown immediately.
3241
- When attempts are exhausted, the last QueryException is thrown; if somehow no exception was thrown, a RuntimeException is raised.
42+
- Requires PHP 8.2+ and Laravel 11.0+

composer.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
"src/Helper.php"
1717
]
1818
},
19+
"autoload-dev": {
20+
"psr-4": {
21+
"Tests\\": "tests/"
22+
}
23+
},
1924
"extra": {
2025
"laravel": {
2126
"providers": [
@@ -28,5 +33,15 @@
2833
"name": "Ahed Wakim",
2934
"email": "[email protected]"
3035
}
31-
]
36+
],
37+
"require-dev": {
38+
"friendsofphp/php-cs-fixer": "^3.88",
39+
"phpunit/phpunit": "^12.4"
40+
},
41+
"scripts": {
42+
"fix": "php-cs-fixer fix --config=.php-cs-fixer.php",
43+
"fix:dry": "php-cs-fixer fix --config=.php-cs-fixer.php --dry-run --diff",
44+
"fix:ci": "php-cs-fixer fix --config=.php-cs-fixer.php --using-cache=no --dry-run",
45+
"test": "vendor/bin/phpunit --configuration phpunit.xml --colors=always"
46+
}
3247
}

0 commit comments

Comments
 (0)