Adakah yang bisa menjelaskan parameter isolasi & propagasi apa untuk @Transactional
anotasi melalui contoh dunia nyata?
Pada dasarnya kapan dan mengapa saya harus memilih untuk mengubah nilai standarnya.
Adakah yang bisa menjelaskan parameter isolasi & propagasi apa untuk @Transactional
anotasi melalui contoh dunia nyata?
Pada dasarnya kapan dan mengapa saya harus memilih untuk mengubah nilai standarnya.
Pertanyaan bagus, meski bukan hal yang sepele untuk dijawab.
Menentukan bagaimana transaksi saling berhubungan. Opsi umum:
Required
: Kode akan selalu berjalan dalam transaksi. Membuat transaksi baru atau menggunakan kembali jika tersedia.Requires_new
: Kode akan selalu berjalan dalam transaksi baru. Tangguhkan transaksi saat ini jika ada.Menentukan kontrak data antar transaksi.
Read Uncommitted
: Memungkinkan pembacaan kotor.Read Committed
: Tidak mengizinkan pembacaan kotor.Repeatable Read
: Jika satu baris dibaca dua kali dalam transaksi yang sama, hasilnya akan selalu sama.Serializable
: Melakukan semua transaksi secara berurutan.Level yang berbeda memiliki karakteristik kinerja yang berbeda dalam aplikasi multi-threaded. Saya pikir jika Anda memahami dirty reads
konsepnya, Anda akan dapat memilih opsi yang baik.
Contoh kapan pembacaan kotor dapat terjadi:
thread 1 thread 2
| |
write(x) |
| |
| read(x)
| |
rollback |
v v
value (x) is now dirty (incorrect)
Jadi default waras (jika dapat diklaim) bisa Read Committed
, yang hanya memungkinkan Anda membaca nilai yang telah dilakukan oleh transaksi berjalan lainnya, dalam kombinasi dengan tingkat propagasi Required
. Maka Anda dapat bekerja dari sana jika aplikasi Anda memiliki kebutuhan lain.
Contoh praktis tentang di mana transaksi baru akan selalu dibuat saat memasuki provideService
rutinitas dan selesai saat meninggalkan:
public class FooService {
private Repository repo1;
private Repository repo2;
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void provideService() {
repo1.retrieveFoo();
repo2.retrieveFoo();
}
}
Kalau saja kita menggunakan Required
, transaksi akan tetap terbuka jika transaksi sudah terbuka ketika memasuki rutin. Perhatikan juga bahwa hasil dari a rollback
dapat berbeda karena beberapa eksekusi dapat mengambil bagian dalam transaksi yang sama.
Kami dapat dengan mudah memverifikasi perilaku dengan tes dan melihat bagaimana hasilnya berbeda dengan tingkat propagasi:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:/fooService.xml")
public class FooServiceTests {
private @Autowired TransactionManager transactionManager;
private @Autowired FooService fooService;
@Test
public void testProvideService() {
TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
fooService.provideService();
transactionManager.rollback(status);
// assert repository values are unchanged ...
}
Dengan tingkat propagasi
Requires new
: Kita harapkan fooService.provideService()
itu tidak digulung kembali karena dibuat itu sendiri sub-transaksi.
Required
: kami harapkan semuanya dibatalkan dan toko dukungan tidak berubah.
sessionFactory.getCurrentTransaction()
ditambahkan tidak perlu berjalanHibernateTemplate
lagi untuk mengelola transaksi. Saya menghapusnya :)PROPAGATION_REQUIRED = 0 ; Jika DataSourceTransactionObject T1 sudah dimulai untuk Metode M1.Jika untuk Metode lain objek Transaksi M2 diperlukan, tidak ada objek Transaksi baru dibuat. Objek yang sama T1 digunakan untuk M2
PROPAGATION_MANDATORY = 2 ; Metode harus dijalankan dalam suatu transaksi. Jika tidak ada transaksi yang sedang berlangsung, pengecualian akan dilemparkan
PROPAGATION_REQUIRES_NEW = 3 ; Jika DataSourceTransactionObject T1 sudah dimulai untuk Metode M1 dan sedang dalam proses (mengeksekusi metode M1). Jika metode lain M2 mulai dijalankan maka T1 ditangguhkan selama durasi metode M2 dengan DataSourceTransactionObject T2 baru untuk M2.M2 berjalan dalam konteks transaksi sendiri
PROPAGATION_NOT_SUPPORTED = 4 ; Jika DataSourceTransactionObject T1 sudah mulai untuk Metode M1.Jika metode lain M2 dijalankan secara bersamaan. Maka M2 tidak boleh berjalan dalam konteks transaksi. T1 ditangguhkan hingga M2 selesai.
PROPAGATION_NEVER = 5 ; Tidak ada metode yang berjalan dalam konteks transaksi.
Tingkat isolasi: Ini tentang seberapa besar transaksi dapat dipengaruhi oleh kegiatan transaksi bersamaan lainnya. Ini adalah konsistensi pendukung yang meninggalkan data melintasi banyak tabel dalam keadaan konsisten. Ini melibatkan penguncian baris dan / atau tabel dalam database.
Masalah dengan beberapa transaksi
Skenario 1. Jika transaksi T1 membaca data dari tabel A1 yang ditulis oleh transaksi konkuren lain T2.Jika dalam perjalanan T2 adalah rollback, data yang diperoleh oleh T1 tidak valid.Eg a = 2 adalah data asli. Jika T1 membaca a = 1 yang ditulis oleh T2.Jika T2 rollback maka a = 1 akan rollback ke a = 2 di DB. Namun, Sekarang, T1 memiliki a = 1 tetapi dalam tabel DB diubah menjadi a = 2.
Skenario2 . Jika transaksi T1 membaca data dari tabel A1. Jika transaksi bersamaan lainnya (T2) memperbarui data pada tabel A1. Kemudian data yang dibaca T1 berbeda dari tabel A1. Karena T2 telah memperbarui data pada tabel A1.Eg jika T1 baca a = 1 dan T2 memperbarui a = 2.Lalu a! = b.
Skenario 3. Jika transaksi T1 membaca data dari tabel A1 dengan jumlah baris tertentu. Jika transaksi bersamaan lainnya (T2) menyisipkan lebih banyak baris pada tabel A1. Jumlah baris yang dibaca oleh T1 berbeda dari baris pada tabel A1
Skenario 1 disebut Dirty reads.
Skenario 2 disebut Non-repeatable reads.
Skenario 3 disebut Phantom reads.
Jadi, level isolasi adalah perluasan di mana Skenario 1, Skenario 2, Skenario 3 dapat dicegah. Anda dapat memperoleh tingkat isolasi lengkap dengan menerapkan penguncian. Itu mencegah pembacaan dan penulisan data yang bersamaan terjadi, tetapi hal itu mempengaruhi kinerja. Tingkat isolasi tergantung pada aplikasi ke aplikasi berapa banyak isolasi yang diperlukan.
ISOLATION_READ_UNCOMMITTED : Memungkinkan untuk membaca perubahan yang belum dilakukan. Ini menderita dari Skenario 1, Skenario 2, Skenario 3
ISOLATION_READ_COMMITTED : Memungkinkan pembacaan dari transaksi bersamaan yang telah dilakukan. Mungkin menderita dari Skenario 2 dan Skenario 3. Karena transaksi lain mungkin memperbarui data.
ISOLATION_REPEATABLE_READ : Banyak pembacaan dari bidang yang sama akan menghasilkan hasil yang sama sampai diubah dengan sendirinya. Mungkin menderita Skenario 3.Karena transaksi lain mungkin memasukkan data
ISOLATION_SERIALIZABLE : Skenario 1, Skenario 2, Skenario 3 tidak pernah terjadi. Ini adalah isolasi lengkap. Ini melibatkan penguncian penuh. Ini menghasilkan kinerja karena penguncian.
Anda dapat menguji menggunakan
Anda dapat men-debug dan melihat hasilnya dengan nilai yang berbeda untuk isolasi dan propagasi.
sumber
Penjelasan yang cukup tentang setiap parameter diberikan oleh jawaban lain; Namun Anda meminta contoh dunia nyata, inilah yang menjelaskan tujuan berbagai opsi propagasi :
Misalkan Anda bertanggung jawab untuk menerapkan layanan pendaftaran di mana email konfirmasi dikirimkan kepada pengguna. Anda datang dengan dua objek layanan, satu untuk mendaftarkan pengguna dan satu untuk mengirim e-mail, yang disebut belakangan di dalam yang pertama. Misalnya sesuatu seperti ini:Anda mungkin telah memperhatikan bahwa layanan kedua adalah tipe propagasi REQUIRES_NEW dan terlebih lagi kemungkinannya melempar pengecualian (server SMTP down, email yang tidak valid atau alasan lain). Anda mungkin tidak ingin seluruh proses untuk roll-back, seperti menghapus informasi pengguna dari basis data atau hal lain; oleh karena itu Anda memanggil layanan kedua dalam transaksi terpisah.
Kembali ke contoh kami, kali ini Anda khawatir tentang keamanan basis data, jadi Anda mendefinisikan kelas DAO Anda dengan cara ini:Berarti bahwa setiap kali objek DAO, dan karenanya potensi akses ke db, dibuat, kita perlu meyakinkan bahwa panggilan itu dilakukan dari dalam salah satu layanan kami, menyiratkan bahwa transaksi langsung harus ada; jika tidak terjadi pengecualian. Oleh karena itu propagasi adalah jenis WAJIB .
sumber
Level isolasi mendefinisikan bagaimana perubahan yang dilakukan pada beberapa repositori data oleh satu transaksi mempengaruhi transaksi bersamaan simultan lainnya, dan juga bagaimana dan kapan perubahan data menjadi tersedia untuk transaksi lain. Ketika kami mendefinisikan transaksi menggunakan kerangka kerja Spring, kami juga dapat mengonfigurasi tingkat isolasi di mana transaksi yang sama akan dieksekusi.
READ_UNCOMMITTED tingkat isolasi menyatakan bahwa suatu transaksi dapat membaca data yang masih tidak dikomit oleh transaksi lain.
READ_COMMITTED tingkat isolasi menyatakan bahwa transaksi tidak dapat membaca data yang belum dilakukan oleh transaksi lain.
REPEATABLE_READ tingkat isolasi menyatakan bahwa jika suatu transaksi membaca satu catatan dari database beberapa kali, hasil dari semua operasi pembacaan tersebut harus selalu sama.
Level isolasi SERIALIZABLE adalah yang paling restriktif dari semua level isolasi. Transaksi dijalankan dengan penguncian di semua tingkatan (baca, rentang, dan penguncian tulis) sehingga tampak seolah-olah dieksekusi secara serial.
Propagasi adalah kemampuan untuk memutuskan bagaimana metode bisnis harus dikemas dalam transaksi logis atau fisik.
Perilaku Spring REQUIRED berarti bahwa transaksi yang sama akan digunakan jika ada transaksi yang sudah dibuka dalam konteks eksekusi metode bean saat ini.
Perilaku REQUIRES_NEW berarti bahwa transaksi fisik baru akan selalu dibuat oleh kontainer.
Perilaku NESTED membuat transaksi Spring bersarang untuk menggunakan transaksi fisik yang sama tetapi menetapkan savepoints antara doa bersarang sehingga transaksi dalam juga dapat rollback secara independen dari transaksi luar.
Perilaku WAJIB menyatakan bahwa transaksi terbuka yang ada harus sudah ada. Jika tidak pengecualian akan dibuang oleh wadah.
Perilaku PERNAH menyatakan bahwa transaksi terbuka yang sudah ada harus belum ada. Jika ada transaksi pengecualian akan dibuang oleh kontainer.
Perilaku NOT_SUPPORTED akan mengeksekusi di luar ruang lingkup transaksi apa pun. Jika transaksi terbuka sudah ada, maka akan dijeda.
Perilaku DUKUNGAN akan mengeksekusi dalam lingkup transaksi jika transaksi terbuka sudah ada. Jika tidak ada transaksi yang sudah dibuka, metode akan tetap menjalankan tetapi dengan cara non-transaksional.
sumber
Transaksi mewakili unit kerja dengan database.
Di
TransactionDefinition
antarmuka pegas yang mendefinisikan properti transaksi yang sesuai dengan Spring.@Transactional
anotasi menjelaskan atribut transaksi pada metode atau kelas.Persepsi penguncian: tingkat isolasi menentukan durasi penguncian.
Baca persepsi: 3 jenis masalah utama berikut terjadi:
UPDATES
dari tx lain.INSERTS
dan / atauDELETES
dari tx lainTingkat isolasi dengan berbagai jenis bacaan:
untuk contoh
sumber
Anda hampir tidak pernah ingin menggunakannya
Read Uncommited
karena tidak benar-benarACID
sesuai.Read Commmited
adalah tempat awal default yang baik.Repeatable Read
mungkin hanya diperlukan dalam skenario pelaporan, rollup, atau agregasi. Perhatikan bahwa banyak DB, postgres yang disertakan sebenarnya tidak mendukung Baca Berulang, Anda harus menggunakannyaSerializable
.Serializable
berguna untuk hal-hal yang Anda tahu harus terjadi sepenuhnya terlepas dari hal lain; pikirkan sepertisynchronized
di Jawa. Serializable berjalan seiring denganREQUIRES_NEW
propagasi.Saya menggunakan
REQUIRES
untuk semua fungsi yang menjalankan permintaan UPDATE atau DELETE serta fungsi tingkat "layanan". Untuk fungsi level DAO yang hanya menjalankan SELECT, saya menggunakanSUPPORTS
yang akan berpartisipasi dalam TX jika sudah dimulai (yaitu dipanggil dari fungsi layanan).sumber
Isolasi Transaksi dan Propagasi Transaksi meskipun terkait tetapi jelas dua konsep yang sangat berbeda. Dalam kedua kasus, default disesuaikan pada komponen batas klien baik dengan menggunakan manajemen transaksi deklaratif atau manajemen transaksi terprogram . Detail setiap level isolasi dan atribut propagasi dapat ditemukan di tautan referensi di bawah ini.
Isolasi Transaksi
Untuk diberikan dua atau lebih transaksi yang berjalan / koneksi ke database, bagaimana dan kapan perubahan dibuat oleh permintaan dalam satu dampak transaksi / terlihat oleh permintaan dalam transaksi yang berbeda. Ini juga terkait dengan jenis penguncian catatan basis data apa yang akan digunakan untuk mengisolasi perubahan dalam transaksi ini dari transaksi lain dan sebaliknya. Ini biasanya diterapkan oleh database / sumber daya yang berpartisipasi dalam transaksi.
.
Propagasi Transaksi
Dalam aplikasi perusahaan untuk setiap permintaan / pemrosesan yang diberikan ada banyak komponen yang terlibat untuk menyelesaikan pekerjaan. Beberapa komponen ini menandai batas (mulai / akhir) dari transaksi yang akan digunakan dalam masing-masing komponen dan sub komponennya. Untuk batas komponen transaksional ini, Propogasi Transaksi menentukan apakah masing-masing komponen akan atau tidak akan berpartisipasi dalam transaksi dan apa yang terjadi jika komponen panggilan sudah atau belum memiliki transaksi yang sudah dibuat / dimulai. Ini sama dengan Atribut Transaksi Java EE. Ini biasanya diterapkan oleh manajer transaksi / koneksi klien.
Referensi:
Manajemen Transaksi Musim Semi
Isolasi Transaksi Wiki (sistem basis data)
Oracle pada Tingkat Isolasi Transaksi
Atribut Transaksi Java EE (propagasi)
Propagasi Transaksi Spring Framework
sumber
Saya telah menjalankan
outerMethod
,method_1
danmethod_2
dengan mode propagasi yang berbeda.Di bawah ini adalah output untuk mode propagasi yang berbeda.
Metode Luar
Method_1
Method_2
sumber
Kami dapat menambahkan ini:
sumber
Anda bisa menggunakan seperti ini:
Anda dapat menggunakan hal ini juga:
sumber