Apakah praktik yang buruk untuk selalu membuat transaksi?

88

Apakah praktik yang buruk untuk selalu membuat transaksi?

Sebagai contoh, itu adalah praktik yang baik untuk membuat transaksi hanya untuk yang sederhana SELECT?

Berapa biaya untuk membuat transaksi padahal sebenarnya tidak perlu?

Bahkan jika Anda menggunakan tingkat isolasi seperti READ UNCOMMITTED, apakah itu praktik yang buruk?

elranu
sumber
1
Melihat dampak BEGIN TRAN SELECT ... COMMITvs hanya SELECTtampaknya ada perbedaan kinerja yang sangat kecil .
Martin Smith

Jawaban:

100

Apakah praktik yang buruk selalu membuat transaksi?

Itu tergantung pada konteks apa yang Anda bicarakan di sini. Jika ini merupakan pembaruan, maka saya akan sangat merekomendasikan menggunakan TRANSAKSI secara eksplisit. Jika itu SELECT maka TIDAK (secara eksplisit).

Tapi tunggu dulu ada lagi yang perlu dipahami: Segala sesuatu di server sql terkandung dalam sebuah transaksi.

Ketika opsi sesi IMPLICIT_TRANSACTIONSadalah OFFdan Anda secara eksplisit menentukan begin trandan commit/rollbackkemudian ini umumnya dikenal sebagai Transaksi Eksplisit . Kalau tidak, Anda mendapatkan transaksi autocommit.

Ketika IMPLICIT_TRANSACTIONSadalah ONsebuah transaksi implisit secara otomatis dimulai ketika menjalankan salah satu jenis pernyataan didokumentasikan dalam buku-buku artikel online (misalnya SELECT/ UPDATE/ CREATE) dan harus berkomitmen atau digulung kembali secara eksplisit. Menjalankan a BEGIN TRANdalam mode ini akan menambah @@TRANCOUNTdan memulai transaksi "bersarang" lainnya)

Untuk mengganti mode yang Anda gunakan, gunakan

SET IMPLICIT_TRANSACTIONS ON

atau

SET IMPLICIT_TRANSACTIONS OFF

select @@OPTIONS & 2

jika di atas mengembalikan 2, Anda berada dalam mode transaksi implisit. Jika mengembalikan 0, Anda berada dalam autocommit.

berapa biaya untuk membuat transaksi padahal sebenarnya tidak perlu?

Diperlukan transaksi untuk membawa basis data dari satu kondisi konsisten ke kondisi konsisten lainnya. Transaksi tidak memiliki biaya karena tidak ada alternatif untuk transaksi. Lihat: Menggunakan Level Isolasi Berbasis Versi Baris

Bahkan jika Anda menggunakan tingkat isolasi read_uncomitted. Apakah praktik yang buruk? karena seharusnya tidak ada masalah dengan penguncian.

READ_UNCOMMITED tingkat isolasi akan memungkinkan pembacaan yang kotor menurut definisi yaitu Satu transaksi akan dapat melihat perubahan yang tidak dikomit dibuat oleh transaksi lainnya. Apa yang dilakukan tingkat isolasi ini adalah, ini melemaskan kepala penguncian - metode memperoleh kunci untuk melindungi konkurensi Database.

Anda dapat menggunakan ini pada tingkat koneksi / kueri, sehingga tidak memengaruhi kueri lain.

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

Ditemukan sebuah artikel yang menarik oleh Jeff Atwood yang menggambarkan Deadlock karena Dining Philosophers Puzzle dan menjelaskan level isolasi snapshot yang sudah dibaca .

SUNTING:

Karena penasaran, saya melakukan beberapa tes mengukur dampak pada T-log dengan penghitung Perfmon seperti Log Bytes Flushed / Sec, Log Flush Waits / Sec (Jumlah komit per detik yang menunggu LOG ​​flush terjadi) seperti grafik di bawah ini:

masukkan deskripsi gambar di sini

Kode sampel :

create table testTran (id int, Name varchar(8))
go

-- 19 sec
-- Autocommit transaction
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
---------------------------------------------------
-- 2 sec
-- Implicit transaction
SET IMPLICIT_TRANSACTIONS ON
declare @i int
set @i = 0
while @i < 100000
begin 
insert into testTran values (1,'Kin Shah')
set @i = @i+1
end
COMMIT;
SET IMPLICIT_TRANSACTIONS OFF


----------------------------------------------------
-- 2 sec
-- Explicit transaction
declare @i int
set @i = 0
BEGIN TRAN
WHILE @i < 100000
Begin
INSERT INTO testTran values (1,'Kin Shah')
set @i = @i+1
End
COMMIT TRAN

Transaksi Autocommit : (Diedit seperti yang disorot oleh @TravisGan)

  • Masukkan waktu 19 detik.
  • Setiap Autocommit akan mem-flush buffer T-log ke disk karena autocomit (setelah @TravisGan disorot, dan saya melewatkan itu untuk menyebutkan).
  • Proses CHECKPOINT akan selesai dengan cepat karena jumlah buffer log kotor yang diperlukan untuk memerah akan lebih sedikit karena sering keheningan.

IMPLICIT & Transaksi Eksplisit:

  • Masukkan waktu 2 detik.
  • Untuk transaksi EXPLICIT, buffer log hanya akan memerah ketika sudah penuh.
  • Bertentangan dengan transaksi Autocommit, dalam transaksi EXPLICIT, proses CHECKPOINT akan memakan waktu lebih lama karena akan memiliki lebih banyak buffer log untuk disiram (ingat bahwa buffer log disiram hanya ketika mereka penuh).

Ada transaksi sys.dm_tran_database_transaksi DMV yang akan mengembalikan informasi tentang Transaksi di tingkat basis data.

Jelas, ini lebih merupakan tes sederhana untuk menunjukkan dampaknya. Faktor-faktor lain seperti subsistem disk, pengaturan pertumbuhan otomatis basis data, ukuran awal basis data, proses lain yang berjalan di server \ database yang sama, dll akan memiliki pengaruh juga.

Dari tes di atas, hampir tidak ada perbedaan antara transaksi Implisit & Eksplisit.

Terima kasih kepada @TravisGan karena telah membantu menambahkan lebih banyak pada jawabannya.

Kin Shah
sumber
35

Pernyataan SQL selalu berjalan dalam transaksi. Jika Anda tidak memulai satu secara eksplisit, setiap pernyataan SQL akan berjalan dalam transaksi itu sendiri.

Satu-satunya pilihan adalah apakah Anda menggabungkan banyak laporan dalam satu transaksi. Transaksi yang menjangkau banyak laporan meninggalkan kunci yang mengganggu konkurensi. Jadi "selalu" membuat transaksi bukanlah ide yang baik. Anda harus menyeimbangkan biaya dengan manfaatnya.

Andomar
sumber
1

Masalahnya adalah apakah sekelompok operasi harus diperlakukan sebagai tindakan tunggal. Dengan kata lain semua operasi harus diselesaikan dan dilakukan dengan sukses atau tidak ada operasi yang dapat dilakukan. Jika Anda memiliki skenario yang mengharuskan Anda membaca data awal dan kemudian melakukan pembaruan berdasarkan data itu maka pembacaan awal mungkin harus menjadi bagian dari transaksi. Catatan: Saya menghindari Select / Insert / Update sengaja. Cakupan transaksi sebenarnya mungkin pada tingkat aplikasi dan melibatkan beberapa operasi database. Pikirkan pola-pola klasik seperti Reservasi Kursi Pesawat atau Penarikan / Penarikan Saldo Bank. Seseorang harus mengambil pandangan yang lebih luas dari masalah untuk memastikan seluruh aplikasi menghasilkan data yang konsisten dan dapat diandalkan.

sinar
sumber