በInterSystems IRIS globals ውስጥ ያሉ ግብይቶች

በInterSystems IRIS globals ውስጥ ያሉ ግብይቶችInterSystems IRIS DBMS ውሂብን ለማከማቸት አስደሳች አወቃቀሮችን ይደግፋል - ግሎባልስ። በመሰረቱ፣ እነዚህ በግብይቶች መልክ የተለያዩ ተጨማሪ መልካም ነገሮች ያላቸው ባለብዙ ደረጃ ቁልፎች፣ የውሂብ ዛፎችን ለመሻገር ፈጣን ተግባራት፣ መቆለፊያዎች እና የራሱ ObjectScript ቋንቋ ናቸው።

ስለ ግሎባልስ በተከታታዩ መጣጥፎች ውስጥ የበለጠ ያንብቡ “ግሎባልስ መረጃን ለማከማቸት ውድ ሰይፎች ናቸው”

ዛፎች. ክፍል 1
ዛፎች. ክፍል 2
ትንሽ ድርድሮች። ክፍል 3

በግሎባልስ ውስጥ ግብይቶች እንዴት እንደሚተገበሩ፣ ምን አይነት ባህሪያት እንዳሉ ለማወቅ ፍላጎት አደረብኝ። ከሁሉም በላይ ይህ ከተለመደው ጠረጴዛዎች ይልቅ መረጃን ለማከማቸት ሙሉ ለሙሉ የተለየ መዋቅር ነው. በጣም ዝቅተኛ ደረጃ።

ከግንኙነት የውሂብ ጎታዎች ንድፈ ሐሳብ እንደሚታወቀው, የግብይቶች ጥሩ ትግበራ መስፈርቶቹን ማሟላት አለበት አሲድ:

ሀ - አቶሚክ (አቶሚክ). በግብይቱ ውስጥ የተደረጉ ለውጦች በሙሉ ወይም በጭራሽ አይመዘገቡም።

ሐ - ወጥነት. ግብይቱ ከተጠናቀቀ በኋላ የውሂብ ጎታው ሎጂካዊ ሁኔታ ከውስጥ ወጥነት ያለው መሆን አለበት። በብዙ መልኩ ይህ መስፈርት ፕሮግራመርን ይመለከታል፣ ነገር ግን በ SQL ዳታቤዝ ውስጥ የውጭ ቁልፎችንም ይመለከታል።

እኔ - ማግለል. በትይዩ የሚሰሩ ግብይቶች እርስበርስ መነካካት የለባቸውም።

D - ዘላቂ. ግብይቱ በተሳካ ሁኔታ ከተጠናቀቀ በኋላ በዝቅተኛ ደረጃዎች ላይ ያሉ ችግሮች (የኃይል ውድቀት, ለምሳሌ) በግብይቱ የተለወጠውን ውሂብ ላይ ተጽዕኖ ማድረግ የለባቸውም.

ግሎባልስ ተዛማጅ ያልሆኑ የመረጃ አወቃቀሮች ናቸው። በጣም ውስን በሆነ ሃርድዌር ላይ እጅግ በጣም በፍጥነት እንዲሰሩ ተደርገው የተሰሩ ናቸው። በግሎባልስ በመጠቀም የግብይቶችን ትግበራ እንመልከት ኦፊሴላዊ IRIS docker ምስል.

በ IRIS ውስጥ ግብይቶችን ለመደገፍ፣ የሚከተሉት ትዕዛዞች ጥቅም ላይ ይውላሉ። ትጀምር, TCOMMIT, ትሮልባክ.

1. Atomity

ለመፈተሽ ቀላሉ መንገድ አቶሚዝም ነው። ከዳታቤዝ ኮንሶል እንፈትሻለን።

Kill ^a
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TCOMMIT

ከዚያም እንጨርሰዋለን፡-

Write ^a(1), “ ”, ^a(2), “ ”, ^a(3)

እናገኛለን፡-

1 2 3

ሁሉ ነገር ጥሩ ነው. Atomity ተጠብቆ ይቆያል: ሁሉም ለውጦች ተመዝግበዋል.

ስራውን እናወሳስበው, ስህተትን እናስተዋውቅ እና ግብይቱ እንዴት እንደሚቀመጥ, በከፊል ወይም ሙሉ በሙሉ እንይ.

የአቶሚክነት ሁኔታን እንደገና እንፈትሽ፡

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3

ከዚያም እቃውን በኃይል እናቆማለን, አስነሳነው እና እናያለን.

docker kill my-iris

ይህ ትእዛዝ ሂደቱን ወዲያውኑ ለማቆም SIGKILL ምልክት ስለሚልክ ከኃይል መዘጋት ጋር እኩል ነው።

ምናልባት ግብይቱ በከፊል ተቀምጧል?

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

- አይ፣ አልተረፈም።

የመመለሻ ትዕዛዙን እንሞክር፡-

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TROLLBACK

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

ምንም ነገር አልተረፈም።

2. ወጥነት

በአለምአቀፍ ደረጃ ላይ በተመሰረቱ የመረጃ ቋቶች ውስጥ ቁልፎች እንዲሁ በግሎባልስ ላይ ስለሚደረጉ (አለምአቀፍ ከግንኙነት ሰንጠረዥ ይልቅ መረጃን ለማከማቸት ዝቅተኛ ደረጃ መዋቅር መሆኑን ላስታውስዎት) የወጥነት መስፈርቱን ለማሟላት የቁልፉ ለውጥ መካተት አለበት። በአለምአቀፍ ለውጥ ተመሳሳይ ግብይት.

ለምሳሌ፣ ዓለም አቀፋዊ ^ ሰው አለን፣ በውስጡም ስብዕናዎችን የምናከማችበት እና TINን እንደ ቁልፍ እንጠቀማለን።

^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
...

በአያት ስም እና የመጀመሪያ ስም ፈጣን ፍለጋ ለማድረግ ^ ኢንዴክስ ቁልፍ ሠራን።

^index(‘Kamenev’, ‘Sergey’, 1234567) = 1

የመረጃ ቋቱ ወጥነት ያለው እንዲሆን፣ ስብዕናውን እንደሚከተለው ማከል አለብን።

TSTART
^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
^index(‘Kamenev’, ‘Sergey’, 1234567) = 1
TCOMMIT

በዚህ መሠረት፣ ስንሰርዝ ግብይትንም መጠቀም አለብን፡-

TSTART
Kill ^person(1234567)
ZKill ^index(‘Kamenev’, ‘Sergey’, 1234567)
TCOMMIT

በሌላ አነጋገር የወጥነት መስፈርት ማሟላት ሙሉ በሙሉ በፕሮግራመር ትከሻ ላይ ነው. ነገር ግን ወደ ግሎባልስ ስንመጣ, ይህ የተለመደ ነው, በዝቅተኛ ደረጃ ተፈጥሮ ምክንያት.

3. ማግለል

የዱር እንስሳት የሚጀምሩት እዚህ ነው. ብዙ ተጠቃሚዎች በተመሳሳይ የውሂብ ጎታ ላይ ይሰራሉ, ተመሳሳዩን ውሂብ ይቀይራሉ.

ሁኔታው ብዙ ተጠቃሚዎች በአንድ ጊዜ ከተመሳሳይ ኮድ ማከማቻ ጋር ሲሰሩ እና በአንድ ጊዜ በብዙ ፋይሎች ላይ ለውጦችን ለማድረግ ሲሞክሩ ሁኔታው ​​​​ይነጻጸራል።

የውሂብ ጎታው ሁሉንም በቅጽበት መደርደር አለበት። በከባድ ኩባንያዎች ውስጥ የስሪት ቁጥጥር (ቅርንጫፎችን ለማዋሃድ ፣ ግጭቶችን ለመፍታት ፣ ወዘተ) ኃላፊነት ያለው ልዩ ሰው እንኳን አለ ፣ እና የውሂብ ጎታ ይህንን ሁሉ በእውነተኛ ጊዜ ማድረግ አለበት ፣ የተግባሩ ውስብስብነት እና ትክክለኛነት። የውሂብ ጎታ ንድፍ እና የሚያገለግለው ኮድ.

የውሂብ ጎታው በተመሳሳይ ውሂብ ላይ እየሰሩ ከሆነ ግጭቶችን ለማስወገድ በተጠቃሚዎች የተከናወኑ ድርጊቶችን ትርጉም ሊረዳ አይችልም. ከሌላው ጋር የሚጋጭ አንድ ግብይት ብቻ መቀልበስ ወይም በቅደም ተከተል ሊያስፈጽማቸው ይችላል።

ሌላው ችግር ግብይት በሚፈፀምበት ወቅት (ከመፈጸም በፊት) የመረጃ ቋቱ ሁኔታ የማይጣጣም ሊሆን ስለሚችል ሌሎች ግብይቶች በተዛማጅ የውሂብ ጎታዎች ውስጥ የሚገኘውን ወጥነት የሌለው የውሂብ ጎታ ሁኔታ እንዳይደርሱበት የሚፈለግ ነው። በብዙ መንገዶች፡ ቅጽበተ-ፎቶዎችን መፍጠር፣ ባለብዙ ስሪት ረድፎች እና ወዘተ.

ግብይቶችን በትይዩ በሚፈጽሙበት ጊዜ, እርስ በእርሳቸው ጣልቃ እንዳይገቡ ለእኛ አስፈላጊ ነው. ይህ የመገለል ንብረት ነው።

SQL 4 የብቸኝነት ደረጃዎችን ይገልጻል፡-

  • ያልተፈቀዱትን ያንብቡ
  • ቁርጠኝነትን ያንብቡ
  • ሊደገም የሚችል ማንበብ
  • SERIALIZABLE

እያንዳንዱን ደረጃ ለየብቻ እንመልከታቸው። እያንዳንዱን ደረጃ የመተግበር ወጪዎች ከሞላ ጎደል በከፍተኛ ደረጃ ያድጋሉ።

ያልተፈቀዱትን ያንብቡ - ይህ በጣም ዝቅተኛው የመገለል ደረጃ ነው, ግን በተመሳሳይ ጊዜ በጣም ፈጣን ነው. ግብይቶች እርስ በርስ የተደረጉ ለውጦችን ማንበብ ይችላሉ.

ቁርጠኝነትን ያንብቡ የሚቀጥለው የመገለል ደረጃ ነው፣ ይህም ስምምነት ነው። ግብይቶች ከመግባታቸው በፊት አንዳቸው የሌላውን ለውጥ ማንበብ አይችሉም፣ ነገር ግን ከመግባቱ በኋላ የተደረጉ ማናቸውንም ለውጦች ማንበብ ይችላሉ።

ረጅም ግብይት ካለን T1 ፣ በቲ 2 ፣ T3 ... Tn ግብይቶች ውስጥ የተከናወነ ሲሆን ፣ እንደ T1 ተመሳሳይ ውሂብ ይሠራ ነበር ፣ ከዚያ በ T1 ውስጥ መረጃን ስንጠይቅ በእያንዳንዱ ጊዜ የተለየ ውጤት እናገኛለን ። ይህ ክስተት የማይደገም ንባብ ይባላል።

ሊደገም የሚችል ማንበብ - በዚህ የመነጠል ደረጃ ላይ እኛ የማይደገም የማንበብ ክስተት የለንም ፣ ምክንያቱም ለእያንዳንዱ መረጃ መረጃን ለማንበብ ጥያቄ ፣ የውጤት ውሂብ ቅጽበታዊ ገጽ እይታ ይፈጠራል እና በተመሳሳይ ግብይት ውስጥ እንደገና ጥቅም ላይ ሲውል ፣ ከቅጽበተ-ፎቶው የተገኘው መረጃ። ጥቅም ላይ ይውላል. ሆኖም፣ በዚህ የመነጠል ደረጃ ላይ የውሸት መረጃ ማንበብ ይቻላል። ይህ በትይዩ በተደረጉ ግብይቶች የታከሉ አዳዲስ ረድፎችን ማንበብን ይመለከታል።

SERIALIZABLE - ከፍተኛው የሙቀት መከላከያ. በግብይት ውስጥ በማንኛውም መንገድ ጥቅም ላይ የዋለ መረጃ (ማንበብ ወይም መለወጥ) ለሌሎች ግብይቶች ሊገኝ የሚችለው የመጀመሪያው ግብይት ከተጠናቀቀ በኋላ ነው ።

በመጀመሪያ ከዋናው ክር ውስጥ በግብይት ውስጥ ኦፕሬሽኖች መገለል አለመኖሩን እንወቅ. 2 ተርሚናል መስኮቶችን እንክፈት።

Kill ^t

Write ^t(1)
2

TSTART
Set ^t(1)=2

ማግለል የለም። አንደኛው ክር ግብይቱን የከፈተው ሁለተኛው ምን እየሰራ እንደሆነ ይመለከታል።

የተለያዩ ክሮች ግብይቶች በውስጣቸው ምን እየተፈጠረ እንዳለ ካዩ እንይ።

2 ተርሚናል መስኮቶችን እንክፈትና 2 ግብይቶችን በትይዩ እንክፈት።

kill ^t
TSTART
Write ^t(1)
3

TSTART
Set ^t(1)=3

ትይዩ ግብይቶች አንዳቸው የሌላውን ውሂብ ያያሉ። ስለዚህ፣ በጣም ቀላሉን፣ ነገር ግን በጣም ፈጣኑን የማግለል ደረጃ አግኝተናል፣ ያልተፈጸመ አንብብ።

በመርህ ደረጃ, ይህ ለአለምአቀፍ ደረጃ ሊጠበቅ ይችላል, ለዚህም አፈፃፀም ሁልጊዜ ቅድሚያ የሚሰጠው ነው.

በአለምአቀፍ ደረጃ በሚደረጉ ስራዎች ላይ ከፍተኛ የብቸኝነት ደረጃ ብንፈልግስ?

እዚህ የማግለል ደረጃዎች ለምን እንደሚያስፈልግ እና እንዴት እንደሚሰሩ ማሰብ አለብዎት.

ከፍተኛው የማግለል ደረጃ, SERIALIZE, ማለት በትይዩ የተከናወኑ ግብይቶች ውጤት በቅደም ተከተል አፈፃፀማቸው ጋር እኩል ነው, ይህም ግጭቶች አለመኖራቸውን ያረጋግጣል.

ብዙ የተለያዩ አጠቃቀሞች ያላቸውን በ ObjectScript ውስጥ ስማርት መቆለፊያዎችን በመጠቀም ይህንን ማድረግ እንችላለን፡ በትእዛዙ መደበኛ፣ ተጨማሪ እና ብዙ መቆለፍ ይችላሉ። LOCK.

ዝቅተኛ የማግለል ደረጃዎች የውሂብ ጎታ ፍጥነትን ለመጨመር የተነደፉ ግብይቶች ናቸው።

መቆለፊያዎችን በመጠቀም እንዴት የተለያዩ የብቸኝነት ደረጃዎችን ማግኘት እንደምንችል እንይ።

ይህ ኦፕሬተር መረጃን ለመለወጥ የሚያስፈልጉትን ልዩ መቆለፊያዎች ብቻ ሳይሆን የጋራ መቆለፊያ የሚባሉትን እንዲወስዱ ይፈቅድልዎታል ፣ ይህም በንባብ ሂደት ውስጥ በሌሎች ሂደቶች መለወጥ የማይገባውን መረጃ ማንበብ ሲፈልጉ በትይዩ ብዙ ክሮች ሊወስድ ይችላል።

በሩሲያ እና በእንግሊዝኛ ስለ ባለ ሁለት-ደረጃ እገዳ ዘዴ ተጨማሪ መረጃ፡-

→ ባለ ሁለት-ደረጃ እገዳ
→ ባለ ሁለት ደረጃ መቆለፍ

ችግሩ በግብይት ወቅት የውሂብ ጎታው ሁኔታ የማይጣጣም ሊሆን ይችላል, ነገር ግን ይህ የማይጣጣም ውሂብ ለሌሎች ሂደቶች ይታያል. ይህንን እንዴት ማስወገድ ይቻላል?

መቆለፊያዎችን በመጠቀም የመረጃ ቋቱ ሁኔታ ወጥነት ያለው የሚሆንበትን የታይነት መስኮቶችን እንፈጥራለን። እና ሁሉም የተስማሙበት ግዛት እንደዚህ ያሉ የታይነት መስኮቶች መዳረሻ በመቆለፊያዎች ቁጥጥር ይደረግባቸዋል።

በተመሳሳዩ ውሂብ ላይ የተጋሩ መቆለፊያዎች እንደገና ጥቅም ላይ ሊውሉ የሚችሉ ናቸው-በርካታ ሂደቶች ሊወስዷቸው ይችላሉ. እነዚህ መቆለፊያዎች ሌሎች ሂደቶችን ውሂብ እንዳይቀይሩ ይከላከላሉ, ማለትም. ወጥ የሆነ የውሂብ ጎታ ሁኔታ መስኮቶችን ለመመስረት ያገለግላሉ።

ልዩ መቆለፊያዎች ለመረጃ ለውጦች ጥቅም ላይ ይውላሉ - አንድ ሂደት ብቻ እንደዚህ አይነት መቆለፊያ ሊወስድ ይችላል. ልዩ መቆለፊያ በሚከተሉት ሊወሰድ ይችላል፡-

  1. ውሂቡ ነፃ ከሆነ ማንኛውም ሂደት
  2. በዚህ ውሂብ ላይ የጋራ መቆለፊያ ያለው እና ብቸኛ መቆለፊያን ለመጠየቅ የመጀመሪያው የሆነው ሂደት ብቻ ነው።

በInterSystems IRIS globals ውስጥ ያሉ ግብይቶች

የታይነት መስኮቱ እየጠበበ በሄደ ቁጥር ሌሎች ሂደቶች እሱን መጠበቅ ሲኖርባቸው፣ ነገር ግን በውስጡ ያለው የውሂብ ጎታ ሁኔታ የበለጠ ወጥነት ያለው ሊሆን ይችላል።

አንብብ_ተፈፀመ - የዚህ ደረጃ ዋናው ነገር ከሌሎች ክሮች የተወሰደ ውሂብ ብቻ ነው የምናየው። በሌላ ግብይት ውስጥ ያለው ውሂብ ገና ካልተፈጸመ, ከዚያ የድሮውን ስሪቱን እናያለን.

ይህም መቆለፊያው እስኪለቀቅ ድረስ ከመጠበቅ ይልቅ ሥራውን ለማመሳሰል ያስችለናል.

ልዩ ዘዴዎች ከሌሉ በ IRIS ውስጥ ያለውን የድሮውን የውሂብ ስሪት ማየት አንችልም, ስለዚህ በመቆለፊያዎች መስራት አለብን.

በዚህ መሠረት መረጃው ወጥነት ባለው ጊዜ ብቻ እንዲነበብ ለማድረግ የጋራ ቁልፎችን መጠቀም አለብን።

እርስ በርሳችን ገንዘብ የሚያስተላልፍ የተጠቃሚ መሰረት ^ ሰው አለን እንበል።

ከሰው 123 ወደ ሰው 242 የተላለፈበት ጊዜ፡-

LOCK +^person(123), +^person(242)
Set ^person(123, amount) = ^person(123, amount) - amount
Set ^person(242, amount) = ^person(242, amount) + amount
LOCK -^person(123), -^person(242)

ዕዳ ከመውጣቱ በፊት 123 ሰው የገንዘቡን መጠን የሚጠይቅበት ጊዜ በልዩ ብሎክ (በነባሪ) መያያዝ አለበት።

LOCK +^person(123)
Write ^person(123)

እና የመለያውን ሁኔታ በግል መለያዎ ውስጥ ማሳየት ከፈለጉ የጋራ መቆለፊያን መጠቀም ወይም ጨርሶ መጠቀም አይችሉም፡-

LOCK +^person(123)#”S”
Write ^person(123)

ነገር ግን፣ የውሂብ ጎታ ክዋኔዎች በቅጽበት ይከናወናሉ ብለን ከወሰድን (ግሎባልስ ከግንኙነት ሠንጠረዥ በጣም ዝቅተኛ ደረጃ ያለው መዋቅር መሆኑን ላስታውስዎት) የዚህ ደረጃ ፍላጎት ይቀንሳል።

ሊደገም የሚችል ማንበብ - ይህ የማግለል ደረጃ በአንድ ጊዜ ግብይቶች ሊሻሻሉ የሚችሉ ብዙ ንባብ መረጃዎችን ይፈቅዳል።

በዚህ መሰረት የምንለውጠውን መረጃ ለማንበብ የጋራ መቆለፊያ እና በምንቀይረው ውሂብ ላይ ልዩ መቆለፊያዎችን ማድረግ አለብን።

እንደ እድል ሆኖ, የ LOCK ኦፕሬተር ሁሉንም አስፈላጊ መቆለፊያዎች በዝርዝር እንዲዘረዝሩ ይፈቅድልዎታል, ከነዚህም ውስጥ ብዙ ሊሆኑ ይችላሉ, በአንድ መግለጫ ውስጥ.

LOCK +^person(123, amount)#”S”
чтение ^person(123, amount)

ሌሎች ክዋኔዎች (በዚህ ጊዜ ትይዩ ክሮች ^ ሰው (123 ፣ መጠን) ለመለወጥ ይሞክራሉ ፣ ግን አይችሉም)

LOCK +^person(123, amount)
иСПононио ^person(123, amount)
LOCK -^person(123, amount)

чтение ^person(123, amount)
LOCK -^person(123, amount)#”S”

በነጠላ ሰረዝ የተለዩ መቆለፊያዎችን ሲዘረዝሩ በቅደም ተከተል ይወሰዳሉ፣ ግን ይህን ካደረጉ፡-

LOCK +(^person(123),^person(242))

ከዚያም በአንድ ጊዜ በአቶሚክ ይወሰዳሉ.

ግልጋሎት - በመጨረሻም ሁሉም የጋራ ውሂብ ያላቸው ግብይቶች በቅደም ተከተል እንዲፈጸሙ መቆለፊያዎችን ማዘጋጀት አለብን። ለዚህ አካሄድ፣ አብዛኛው መቆለፊያዎች ብቸኛ መሆን አለባቸው እና ለአፈፃፀም በትንሹ የአለም አካባቢዎች መወሰድ አለባቸው።

በአለምአቀፍ ^ ሰው ውስጥ ስለ ፈንዶች ስለማስወጣት ከተነጋገርን, ለእሱ ተቀባይነት ያለው የ SERIALIZE ማግለል ደረጃ ብቻ ነው, ምክንያቱም ገንዘቡ በጥብቅ በቅደም ተከተል መዋል አለበት, አለበለዚያ ተመሳሳይ መጠን ብዙ ጊዜ ማውጣት ይቻላል.

4. ዘላቂነት

ኮንቴይነሩን ተጠቅሜ በጠንካራ መቁረጥ ሙከራዎችን አደረግሁ

docker kill my-iris

መሰረቱ በደንብ ቻላቸው። ምንም ችግሮች አልተለዩም.

መደምደሚያ

ለአለምአቀፋዊ፣ InterSystems IRIS የግብይት ድጋፍ አለው። እነሱ በእውነት አቶሚክ እና አስተማማኝ ናቸው. እንደ የውጭ ቁልፎች ያሉ ውስብስብ አብሮገነብ ግንባታዎች ስለሌለው በአለምአቀፍ ደረጃ ላይ የተመሰረተ የውሂብ ጎታ ወጥነት እንዲኖረው የፕሮግራም አድራጊ ጥረቶች እና የግብይቶች አጠቃቀም ያስፈልጋል።

መቆለፊያዎችን ሳይጠቀሙ የግሎባልን ማግለል ደረጃ ያልተሰበሰበ ማንበብ ነው፣ እና መቆለፊያዎችን ሲጠቀሙ እስከ SERIALIZE ደረጃ ድረስ ሊረጋገጥ ይችላል።

በአለምአቀፍ ደረጃ የግብይቶች ትክክለኛነት እና ፍጥነት በፕሮግራም አድራጊው ክህሎት ላይ የተመሰረተ ነው: በሚነበቡበት ጊዜ በስፋት የሚጋሩት መቆለፊያዎች ጥቅም ላይ ይውላሉ, የመነጠል ደረጃው ከፍ ባለ መጠን እና በጣም ጠባብ ልዩ መቆለፊያዎች ሲወሰዱ, አፈፃፀሙ ፈጣን ይሆናል.

ምንጭ: hab.com

አስተያየት ያክሉ