Ի՞նչ պետք է անել, եթե երկու աշխատող միաժամանակ դիմում են նույն տվյալներին:
sobes.tech AI
Պատասխան AI-ից
Պետք է ապահովել տվյալների մուտքի հոսքային անվտանգությունը։ Հիմնական մոտեցումները՝
-
Բլոկավորումներ (Locks): Օգտագործվում են կտրուկ հատվածների մուտքը սահմանափակելու համար։ Միայն մեկ հոսք կարող է ունենալ բլոկավորումը տվյալ պահին։
# Մոդել Mutex-ով Ruby-ում require 'thread' $shared_data = 0 $mutex = Mutex.new def increment_data $mutex.lock # Բլոկավորման ձեռքբերում begin # Կրիտիկական հատված temp = $shared_data sleep(0.01) # Աշխատանքի իմիտացիա $shared_data = temp + 1 ensure $mutex.unlock # Բլոկավորման ազատում end end threads = [] 10.times do threads << Thread.new { increment_data } end threads.each(&:join) puts $shared_data # Անպայման կլինի 10 -
Տվյալների բազայի տրանզակցիաներ: Եթե տվյալները պահվում են տվյալների բազայում, օգտագործեք տրանզակցիաներ՝ ատոմիկ գործողությունների համար։ Տրանզակցիայի մեկուսացման մակարդակը որոշում է, թե ինչպես են տեսանելի փոփոխությունները, որոնք կատարվել են այլ տրանզակցիաներով։
# Rails-ում ActiveRecord-ի օրինակով ActiveRecord::Base.transaction do # Բոլոր գործողությունները բլոկում կատարվում են ատոմիկ user = User.find(user_id) user.balance -= amount order = Order.create!(user: user, amount: amount) user.save! # Եթե ինչ-որ բան սխալ լինի, ամբողջ տրանզակցիան հետ է տարվում end -
Ատոմիկ գործողություններ: Որոշ լեզուներ և գրադարաններ տրամադրում են ատոմիկ տվյալների տիպեր կամ գործողություններ, որոնք երաշխավորված են ամբողջությամբ կատարվել առանց միջամտության այլ հոսքերի կողմից։
# Ruby-ն չունի ներքին ատոմիկ տիպեր ցանկացած տվյալների համար, # բայց որոշ գործողություններ (օրինակ, նշանակումը) կարող են լինել ատոմիկ # պարզ տիպերի համար։ Ավելի բարդ սցենարների համար անհրաժեշտ են բլոկավորումներ։ -
Օպտիմիստական համաժամանակության վերահսկում: Փոխարենը բլոկավորումների, յուրաքանչյուր գրառում ունի վերանայման համար թիվ կամ ժամանակային նշան։ Ավելացման ժամանակ ստուգվում է, արդյոք գրառումը փոխվել է այն ժամանակից ի վեր, երբ այն կարդացել է։ Եթե փոխվել է, գործողությունը վերագործարկվում է։
# ActiveRecord::Locking::Optimistic-ի օրինակ # Ավելացրեք `lock_version` (լուծում) ձեր աղյուսակին class Product < ApplicationRecord # ... end product = Product.find(id) # Այլ հոսք նույն արտադրանքը թարմացնում է... begin product.price += 10 product.save! # Գեներացնում է ActiveRecord::StaleObjectError, եթե lock_version-ը փոխվել է rescue ActiveRecord::StaleObjectError # Կոնֆլիկտի մշակումը, օրինակ, վերից բեռնում և կրկին փորձ retry end -
Հաղորդագրության միջնորդներ / հերթեր: Փոխարենը ուղիղ մուտք գործելու տվյալների, աշխատողները ուղարկում են հաղորդագրություններ միջնորդին (օրինակ, RabbitMQ, Sidekiq-ով Redis-ով): Հաղորդագրությունների մշակումը կատարվում է հերթական կամ կառավարելի կարգով, ինչը նվազեցնում է կոնֆլիկտների հավանականությունը։
-
Անփոփոխ օբյեկտների օգտագործում: Եթե տվյալները անփոփոխ են, միաժամանակյա մուտքը նրանց ապահով է, քանի որ ոչ մի աշխատող չի կարող փոխել դրանք։
Ընտրությունը կամ մոտեցումների համակցությունը կախված է տվյալների տեսակից, կատարողականի պահանջներից և ծրագրի ճարտարապետությունից։ Ruby on Rails-ով վեբ ծրագրերում հաճախ օգտագործվում են ActiveRecord տրանզակցիաներ և օպտիմիստական բլոկավորումներ տվյալների բազայում, իսկ ընդհանուր ռեսուրսների համար՝ Mutex։ Պատկերային առաջադրանքները (օրինակ, Sidekiq) սովորաբար մշակվում են հերթերից հաղորդագրություններով, որոնք ապահովում են որոշակի կարգապահություն։