1919final class AtomicService implements AtomicServiceInterface
2020{
2121 public function __construct (
22+ private BookkeeperServiceInterface $ bookkeeperService ,
2223 private DatabaseServiceInterface $ databaseService ,
2324 private StateServiceInterface $ stateService ,
2425 private LockServiceInterface $ lockService ,
@@ -36,23 +37,35 @@ public function __construct(
3637 */
3738 public function blocks (array $ objects , callable $ callback ): mixed
3839 {
39- $ callable = fn () => $ this -> databaseService -> transaction ( $ callback ) ;
40+ $ blockObjects = [] ;
4041 foreach ($ objects as $ object ) {
4142 $ wallet = $ this ->castService ->getWallet ($ object );
42- $ callable = fn () => $ this ->lockService ->block (
43- $ wallet ->uuid ,
44- function () use ($ wallet , $ callable ) {
45- try {
46- $ this ->stateService ->fork ($ wallet ->uuid , $ wallet ->balance );
47- return $ callable ();
48- } finally {
49- $ this ->stateService ->drop ($ wallet ->uuid );
50- }
51- }
52- );
43+ if (! $ this ->lockService ->isBlocked ($ wallet ->uuid )) {
44+ $ blockObjects [] = $ object ;
45+ }
5346 }
5447
55- return $ callable ();
48+ $ callable = function () use ($ blockObjects , $ callback ) {
49+ foreach ($ blockObjects as $ object ) {
50+ $ wallet = $ this ->castService ->getWallet ($ object );
51+ $ this ->stateService ->fork ($ wallet ->uuid , $ this ->bookkeeperService ->amount ($ wallet ));
52+ }
53+ return $ this ->databaseService ->transaction ($ callback );
54+ };
55+
56+ foreach ($ blockObjects as $ object ) {
57+ $ wallet = $ this ->castService ->getWallet ($ object );
58+ $ callable = fn () => $ this ->lockService ->block ($ wallet ->uuid , $ callable );
59+ }
60+
61+ try {
62+ return $ callable ();
63+ } finally {
64+ foreach ($ blockObjects as $ object ) {
65+ $ wallet = $ this ->castService ->getWallet ($ object );
66+ $ this ->stateService ->drop ($ wallet ->uuid );
67+ }
68+ }
5669 }
5770
5871 /**
0 commit comments