Տրանզակցիաներ
Drupal-ն նույնպես աջակցում է տրանզակցիաներին՝ ներառյալ թափանցիկ պահուստային տարբերակ այն տվյալների բազաների համար, որոնք չեն աջակցում տրանզակցիաներին։ Սակայն տրանզակցիաները կարող են բավական բարդ լինել, եթե փորձեք միաժամանակ գործարկել երկու տրանզակցիա։ Այս դեպքի վարքը կախված է տվյալների բազայի տեսակից։
Նման խնդիր գոյություն ունի նաև C/C++ լեզուներում՝ դրսի կողպեքների հետ։ Եթե կոդը արդեն ձեռք է բերել A կողպեքը և փորձի կրկին ձեռք բերել նույն A կողպեքը, կոդը կկանգնի (deadlock): Եթե դուք գրում եք կոդ, որը ստուգում է, արդյոք արդեն ունի կողպեքը և չի փորձում այն կրկին ստանալ, ապա խուսափում եք deadlock-ից, բայց կարող եք նախկինում բացել կողպեքը։
SQL-ում նույն խնդիրը կա։ Եթե ձեր կոդը արդեն գտնվում է տրանզակցիայի մեջ, նոր տրանզակցիայի մեկնարկը անսպասելի և տխուր հետևանք ունի՝ ընթացիկ տրանզակցիայի կոմիտացում և նորի մեկնարկ։
Java-ն լուծում է կողպեքների ներդաշնակության խնդիրը իր կողպեքների միջոցով՝ իրականացնելով ներդաշնակության մակարդակի կառուցվածքի աջակցություն, որը նման է ստորև ներկայացվածին։ Java-ն թույլ է տալիս նշել ֆունկցիաները որպես «synchronized», ինչը заставляет ֆունկցիան սպասել կողպեքը ստանալուն մինչ մեկնարկը և բաց թողնել այն, երբ այն այլևս անհրաժեշտ չէ։ Եթե մեկ synchronized ֆունկցիա կանչում է մյուսը նույն դասում, Java-ն հաշվում է կողպեքի ներդաշնակությունը։ Արտաքին ֆունկցիան ստանում է կողպեքը, ներքինը չի անում կողպեքի գործողություններ, իսկ արտաքին ֆունկցիան բաց է թողնում կողպեքը վերադարձի ժամանակ։
Թեև PHP-ում չենք կարող հայտարարել ֆունկցիաներ որպես «transactional», մենք կարող ենք էմուլացնել Java-ի ներդաշնակության տրամաբանությունը՝ օգտագործելով օբյեկտներ՝ կոնստրուկտորներով և դեստրուկտորներով։ Ֆունկցիան պարզապես կանչում է «$transaction = $connection->startTransaction()» որպես առաջին (կամ գրեթե առաջին) գործողություն՝ ինքն իրեն դարձնելով transactional։ Եթե մի transactional ֆունկցիա կանչում է մյուսը, մեր տրանզակցիայի ընդլայնման մակարդակը ներառում է դրանք՝ չկատարելով transactional գործողություններ (օրինակ՝ տվյալների բազայի տեսանկյունից) ներքին մակարդակներում։
Նոր տրանզակցիա սկսելու համար պարզապես կանչեք $transaction = $connection->startTransaction(); ձեր սեփական կոդում։ Տրանզակցիան բաց կմնա այնքան ժամանակ, որքան փոփոխականը $transaction առկա է տեսանելիության մեջ։ Երբ $transaction ոչնչացվի, տրանզակցիան կնքվի։ Եթե ձեր տրանզակցիան ներառված է մեկ այլ տրանզակցիայի մեջ, Drupal-ը կգրանցի յուրաքանչյուր տրանզակցիա և կնքի ամենաուրսի տրանզակցիան միայն այն ժամանակ, երբ վերջին տրանզակցիայի օբյեկտը դուրս գա տեսանելիությունից, այսինքն՝ բոլոր համապատասխան հարցումները հաջողությամբ ավարտվեն։
Դուք պետք է վերագրեք $connection->startTransaction(); վերադարձվող արժեքը փոփոխականին, ինչպես օրինակ։ Եթե կանչեք մեթոդը առանց վերագրելու վերադարձվող արժեքը, ձեր տրանզակցիան անմիջապես կնքվի, ինչը անիմաստ կդարձնի այն։
Տրանզակցիայի ռոլբեքը կառավարում է կոնեկտորի օբյեկտը ($connection->rollBack()) Drupal 8-ում, բայց սովորաբար պետք է կատարվի տրանզակցիայի ծածկույթի մեթոդով ($action->rollBack())։ Ռոլբեքը պետք է կատարվի transaction-ի մեթոդով, քանի որ այն ռոլբեքում է հենց տվյալ transaction-ը՝ օգտագործելով նրա անունը, որտեղ $connection->rollBack() որպես ստանդարտ սահմանում ունի անունը drupal_transaction և կարող է չհամապատասխանող արդյունքներ տալ, եթե օգտագործվի ներդրված տրանզակցիաների հետ։
Օրինակ:
function my_transaction_function() { // Տրանզակցիան սկսվում է այստեղ։ $transaction = $connection->startTransaction(); try { $id = $connection->insert('example') ->fields([ 'field1' => 'mystring', 'field2' => 5, ]) ->execute(); my_other_function($id); return $id; } catch (Exception $e) { $transaction->rollBack(); watchdog_exception('my_type', $e); } // Կարելի է թողնել $transaction-ը դուրս տեսանելիությունից, // և տրանզակցիան ավտոմատ կնքվի, եթե այն դեռ չի արվել ռոլբեք։ // Սակայն եթե ունեք հավելյալ աշխատանք, պետք է ինքներդ ձեռքով կոմիտեք տրանզակցիան։ $transaction->commit(); // Ավելին կոդը, որը գտնվում է տրանզակցիայի դրսում։ } function my_other_function($id) { // Տրանզակցիան դեռ բաց է այստեղ։ if ($id % 2 == 0) { $connection->update('example') ->condition('id', $id) ->fields(['field2' => 10]) ->execute(); } }
Drupal’s online documentation is © 2000-2020 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License.