8.1 ID Transaksi

Ia ditetapkan sebagai XID atau TxID (jika ada perbezaan, beritahu saya). Cap masa boleh digunakan sebagai TxID, yang boleh bermain ke tangan jika kita ingin memulihkan semua tindakan ke satu masa. Masalah boleh timbul jika cap masa tidak cukup berbutir - maka transaksi boleh mendapatkan ID yang sama.

Oleh itu, pilihan yang paling boleh dipercayai ialah menjana ID prod UUID yang unik. Dalam Python ini sangat mudah:

>>> import uuid 
>>> str(uuid.uuid4()) 
'f50ec0b7-f960-400d-91f0-c42a6d44e3d0' 
>>> str(uuid.uuid4()) 
'd15bed89-c0a5-4a72-98d9-5507ea7bc0ba' 

Terdapat juga pilihan untuk mencincang satu set data penentu transaksi dan menggunakan cincang ini sebagai TxID.

8.2 Cuba semula

Jika kita tahu bahawa fungsi atau program tertentu adalah idempoten, maka ini bermakna kita boleh dan harus cuba mengulangi panggilannya sekiranya berlaku ralat. Dan kita hanya perlu bersedia untuk fakta bahawa sesetengah operasi akan memberikan ralat - memandangkan aplikasi moden diedarkan melalui rangkaian dan perkakasan, ralat itu harus dianggap bukan sebagai pengecualian, tetapi sebagai norma. Ralat boleh berlaku disebabkan oleh ranap pelayan, ralat rangkaian, kesesakan aplikasi jauh. Bagaimanakah aplikasi kita seharusnya berkelakuan? Betul, cuba ulangi operasi.

Memandangkan sekeping kod boleh menyebut lebih daripada satu halaman keseluruhan perkataan, mari gunakan satu contoh untuk memahami cara mekanisme mencuba semula naif sepatutnya berfungsi dengan baik. Saya akan menunjukkan ini menggunakan perpustakaan Tenacity (ia direka dengan sangat baik sehinggakan walaupun anda tidak merancang untuk menggunakannya, contoh tersebut harus menunjukkan kepada anda bagaimana anda boleh mereka bentuk mekanisme berulang):

import logging
import random
import sys
from tenacity import retry, stop_after_attempt, stop_after_delay, wait_exponential, retry_if_exception_type, before_log

logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
logger = logging.getLogger(__name__)

@retry(
	stop=(stop_after_delay(10) | stop_after_attempt(5)),
	wait=wait_exponential(multiplier=1, min=4, max=10),
	retry=retry_if_exception_type(IOError),
	before=before_log(logger, logging.DEBUG)
)
def do_something_unreliable():
	if random.randint(0, 10) > 1:
    	raise IOError("Broken sauce, everything is hosed!!!111one")
	else:
    	return "Awesome sauce!"

print(do_something_unreliable.retry.statistics)

> Untuk berjaga-jaga, saya akan katakan: \@retry(...) ialah sintaks Python khas yang dipanggil "penghias". Ia hanyalah fungsi cuba semula(...) yang membungkus fungsi lain dan melakukan sesuatu sebelum atau selepas ia dilaksanakan.

Seperti yang kita lihat, percubaan semula boleh direka bentuk secara kreatif:

  • Anda boleh mengehadkan percubaan mengikut masa (10 saat) atau bilangan percubaan (5).
  • Boleh menjadi eksponen (iaitu, 2 ** beberapa bilangan bertambah n ). atau dengan cara lain (contohnya, tetap) untuk meningkatkan masa antara percubaan berasingan. Varian eksponen dipanggil "congestion collapse".
  • Anda boleh mencuba semula hanya untuk jenis ralat tertentu (IOError).
  • Percubaan cuba semula boleh didahului atau diselesaikan oleh beberapa entri khas dalam log.

Sekarang kita telah menamatkan kursus pejuang muda dan mengetahui asas binaan yang kita perlukan untuk bekerja dengan urus niaga di bahagian aplikasi, mari kita berkenalan dengan dua kaedah yang membolehkan kita melaksanakan transaksi dalam sistem teragih.

8.3 Alat lanjutan untuk pencinta transaksi

Saya hanya akan memberikan definisi yang agak umum, kerana topik ini layak untuk artikel besar yang berasingan.

Komit dua fasa (2pc) . 2pc mempunyai dua fasa: fasa penyediaan dan fasa komit. Semasa fasa penyediaan, semua perkhidmatan mikro akan diminta untuk menyediakan beberapa perubahan data yang boleh dilakukan secara atom. Setelah semuanya bersedia, fasa komitmen akan membuat perubahan sebenar. Untuk menyelaraskan proses, penyelaras global diperlukan, yang mengunci objek yang diperlukan - iaitu, objek tersebut menjadi tidak boleh diakses untuk perubahan sehingga penyelaras membuka kuncinya. Jika perkhidmatan mikro tertentu tidak bersedia untuk perubahan (contohnya, tidak bertindak balas), penyelaras akan membatalkan urus niaga dan memulakan proses rollback.

Mengapa protokol ini bagus? Ia menyediakan atomicity. Selain itu, ia menjamin pengasingan semasa menulis dan membaca. Ini bermakna bahawa perubahan pada satu transaksi tidak dapat dilihat oleh orang lain sehingga penyelaras melakukan perubahan tersebut. Tetapi sifat ini juga mempunyai kelemahan: kerana protokol ini adalah segerak (menyekat), ia melambatkan sistem (walaupun hakikat bahawa panggilan RPC itu sendiri agak perlahan). Dan sekali lagi, terdapat bahaya saling menyekat.

Saga . Dalam corak ini, transaksi teragih dilaksanakan oleh transaksi tempatan tak segerak merentas semua perkhidmatan mikro yang berkaitan. Perkhidmatan mikro berkomunikasi antara satu sama lain melalui bas acara. Jika mana-mana perkhidmatan mikro gagal menyelesaikan transaksi setempatnya, perkhidmatan mikro lain akan melakukan transaksi pampasan untuk melancarkan semula perubahan.

Kelebihan Saga ialah tiada objek yang disekat. Tetapi ada, tentu saja, kelemahan.

Saga sukar untuk dinyahpepijat, terutamanya apabila terdapat banyak perkhidmatan mikro yang terlibat. Satu lagi kelemahan corak Saga ialah ia tidak mempunyai pengasingan bacaan. Iaitu, jika sifat-sifat yang ditunjukkan dalam ACID penting kepada kita, maka Saga tidak begitu sesuai untuk kita.

Apakah yang kita lihat daripada penerangan kedua-dua teknik ini? Hakikat bahawa dalam sistem teragih, tanggungjawab untuk atomicity dan pengasingan terletak pada aplikasi. Perkara yang sama berlaku apabila menggunakan pangkalan data yang tidak menyediakan jaminan ACID. Iaitu, perkara seperti penyelesaian konflik, penarikan balik, komitmen dan membebaskan ruang terletak di bahu pembangun.

8.4 Bagaimanakah saya tahu bila saya memerlukan jaminan ACID?

Apabila terdapat kebarangkalian tinggi bahawa set pengguna atau proses tertentu akan berfungsi pada data yang sama secara serentak .

Maaf atas keterlaluan, tetapi contoh biasa ialah transaksi kewangan.

Apabila perintah di mana urus niaga dilaksanakan adalah penting.

Bayangkan bahawa syarikat anda akan bertukar daripada FunnyYellowChat messenger kepada FunnyRedChat messenger, kerana FunnyRedChat membenarkan anda menghantar gif, tetapi FunnyYellowChat tidak boleh. Tetapi anda bukan hanya menukar utusan - anda memindahkan surat-menyurat syarikat anda dari satu utusan ke yang lain. Anda melakukan ini kerana pengaturcara anda terlalu malas untuk mendokumentasikan program dan proses di suatu tempat secara berpusat, dan sebaliknya mereka menerbitkan segala-galanya dalam saluran yang berbeza dalam messenger. Ya, dan jurujual anda menerbitkan butiran rundingan dan perjanjian di tempat yang sama. Ringkasnya, seluruh hayat syarikat anda ada di sana, dan memandangkan tiada siapa yang mempunyai masa untuk memindahkan semuanya kepada perkhidmatan untuk dokumentasi, dan carian untuk pemesej segera berfungsi dengan baik, anda memutuskan daripada membersihkan runtuhan untuk hanya menyalin semua mesej ke lokasi baharu. Susunan mesej adalah penting

Ngomong-ngomong, untuk surat-menyurat dalam utusan, pesanan itu secara amnya penting, tetapi apabila dua orang menulis sesuatu dalam sembang yang sama pada masa yang sama, maka secara umum tidak begitu penting mesej siapa yang akan muncul dahulu. Jadi, untuk senario tertentu ini, ACID tidak diperlukan.

Contoh lain yang mungkin ialah bioinformatik. Saya tidak faham sama sekali, tetapi saya menganggap bahawa susunan itu penting apabila mentafsir genom manusia. Walau bagaimanapun, saya mendengar bahawa ahli bioinformatika biasanya menggunakan beberapa alat mereka untuk segala-galanya - mungkin mereka mempunyai pangkalan data mereka sendiri.

Apabila anda tidak dapat memberikan pengguna atau memproses data lapuk.

Dan sekali lagi - transaksi kewangan. Sejujurnya, saya tidak dapat memikirkan contoh lain.

Apabila urus niaga belum selesai dikaitkan dengan kos yang ketara. Bayangkan masalah yang boleh timbul apabila doktor dan jururawat sama-sama mengemas kini rekod pesakit dan memadam perubahan satu sama lain pada masa yang sama, kerana pangkalan data tidak boleh mengasingkan transaksi. Sistem penjagaan kesihatan adalah satu lagi bidang, selain kewangan, di mana jaminan ACID cenderung menjadi kritikal.

8.5 Bilakah saya tidak memerlukan ASID?

Apabila pengguna mengemas kini hanya beberapa data peribadi mereka.

Contohnya, pengguna meninggalkan komen atau nota melekit pada halaman web. Atau mengedit data peribadi dalam akaun peribadi dengan pembekal mana-mana perkhidmatan.

Apabila pengguna tidak mengemas kini data sama sekali, tetapi hanya menambah dengan yang baharu (tambah).

Contohnya, aplikasi berjalan yang menyimpan data pada larian anda: berapa banyak anda berlari, untuk masa, laluan, dsb. Setiap larian baharu adalah data baharu dan yang lama tidak diedit sama sekali. Mungkin, berdasarkan data, anda mendapat analitik - dan hanya pangkalan data NoSQL yang baik untuk senario ini.

Apabila logik perniagaan tidak menentukan keperluan untuk susunan tertentu di mana transaksi dilakukan.

Mungkin, bagi blogger Youtube yang mengutip derma untuk pengeluaran bahan baru semasa siaran langsung seterusnya, tidaklah begitu penting siapa, bila dan dalam urutan apa, melemparkan wang kepadanya.

Apabila pengguna akan kekal di halaman web atau tetingkap aplikasi yang sama selama beberapa saat atau bahkan minit, dan oleh itu mereka akan melihat data basi.

Secara teorinya, ini adalah mana-mana media berita dalam talian, atau Youtube yang sama. Atau "Habr". Apabila tidak penting bagi anda bahawa transaksi yang tidak lengkap boleh disimpan sementara dalam sistem, anda boleh mengabaikannya tanpa sebarang kerosakan.

Jika anda mengagregat data daripada banyak sumber, dan data yang dikemas kini pada frekuensi tinggi - contohnya, data tentang penghunian tempat letak kereta di bandar yang berubah sekurang-kurangnya setiap 5 minit, maka secara teori ia tidak akan menjadi masalah besar untuk anda jika pada satu ketika transaksi untuk salah satu tempat letak kereta tidak akan melalui. Walaupun, sudah tentu, ia bergantung pada apa sebenarnya yang anda mahu lakukan dengan data ini.