Apa efek dari memiliki transaksi terbuka di MSSQL terlalu lama?

11

Saya hanya ingin tahu apa yang terjadi jika Anda memulai transaksi dalam DB dan lupa untuk melakukan atau mengembalikannya. Apakah server akan mati? Katakanlah Anda meninggalkannya selama 3 hari.

Ada juga pengguna yang menggunakannya dengan asumsi bahwa pengguna lain tidak tahu bahwa ada transaksi yang tidak tertutup (anggap saja pengguna hanya memasukkan data pada basis data). Apa konsekuensi dari tindakan ini?

JanLeeYu
sumber

Jawaban:

14

Memiliki transaksi terbuka dengan sendirinya hampir tidak memiliki konsekuensi. Sederhana

BEGIN TRANSACTION
-- wait for a while, doing nothing
-- wait a bit longer
COMMIT

akan, paling buruk, menyimpan beberapa byte dari nilai status. Bukan masalah besar.

Sebagian besar program akan melakukan pekerjaan yang sebenarnya dalam transaksi dan ini adalah masalah lain. Tujuan transaksi adalah agar Anda dapat yakin bahwa beberapa fakta di dalam basis data benar secara bersamaan, meskipun ada pengguna lain yang menulis ke basis data yang sama secara bersamaan.

Ambil contoh kanonik mentransfer uang antar rekening bank. Sistem harus memastikan bahwa akun sumber ada, memiliki dana yang cukup, akun tujuan ada, dan bahwa debit dan kredit terjadi atau tidak terjadi. Ini harus menjamin ini sementara transaksi lain terjadi, bahkan mungkin antara dua akun ini. Sistem memastikan ini dengan mengambil kunci pada tabel yang bersangkutan. Kunci apa yang diambil, dan seberapa banyak pekerjaan orang lain yang Anda lihat, dikendalikan oleh tingkat isolasi transaksi .

Jadi, jika Anda melakukan banyak pekerjaan, ada kemungkinan transaksi lain akan mengantri menunggu benda-benda di mana Anda memegang kunci. Ini akan mengurangi throughput keseluruhan sistem. Akhirnya mereka akan mencapai batas waktu habis dan gagal, yang merupakan masalah bagi perilaku sistem secara keseluruhan. Jika Anda menggunakan tingkat isolasi optimis transaksi Anda mungkin gagal ketika Anda mencoba komit karena pekerjaan orang lain.

Memegang kunci membutuhkan sumber daya sistem. Ini adalah memori yang tidak dapat digunakan sistem untuk memproses permintaan lain, mengurangi throughput.

Jika banyak pekerjaan telah dilakukan, sistem dapat memilih untuk melakukan eskalasi kunci . Alih-alih mengunci setiap baris, seluruh tabel akan dikunci. Kemudian lebih banyak pengguna secara bersamaan akan terpengaruh, throughput sistem akan turun lebih jauh dan dampak aplikasi akan lebih besar.

Perubahan data ditulis ke file log, seperti kunci yang melindunginya. Ini tidak dapat dihapus dari log sampai transaksi dilakukan. Karenanya transaksi yang sangat lama dapat menyebabkan file log kembung dengan masalah yang terkait.

Jika pekerjaan saat ini menggunakan tempdb, yang kemungkinan untuk beban kerja besar, sumber daya di sana mungkin terikat sampai akhir transaksi. Dalam kasus ekstrim ini dapat menyebabkan tugas-tugas lain gagal karena tidak ada cukup ruang untuk mereka. Saya memiliki kasus di mana UPDATE kode buruk diisi tempdb sehingga ada disk yang tidak cukup untuk SORT laporan dan laporan gagal.

Jika Anda memilih untuk ROLLBACK transaksi, atau sistem gagal dan pulih, waktu yang dibutuhkan sistem untuk tersedia kembali akan tergantung pada seberapa banyak pekerjaan yang dilakukan. Cukup memiliki transaksi terbuka tidak akan mempengaruhi waktu pemulihan, itu adalah berapa banyak pekerjaan yang dilakukan. Jika transaksi terbuka tetapi tidak ada waktu selama satu jam, pemulihan akan hampir seketika. Jika itu menulis terus-menerus untuk jam itu, aturan praktisnya adalah waktu pemulihan juga akan sekitar satu jam.

Seperti yang Anda lihat, transaksi lama bisa bermasalah. Untuk sistem OLTP praktik terbaik adalah memiliki satu transaksi basis data per transaksi bisnis. Untuk input proses kerja batch dalam blok, dengan sering komit, dan restart kode logika. Biasanya beberapa ribu catatan dapat diproses dalam satu transaksi DB, tetapi ini harus diuji untuk konkurensi dan mengurangi konsumsi.

Jangan tergoda untuk pergi ke ekstrim lain dan menghindari transaksi dan kunci sepenuhnya. Jika Anda perlu mempertahankan konsistensi dalam data Anda (dan mengapa lagi Anda menggunakan basis data?) Level dan transaksi isolasi melayani tujuan yang sangat penting. Pelajari tentang opsi Anda dan tentukan keseimbangan konkurensi dan kebenaran yang siap Anda jalani untuk setiap bagian dari aplikasi Anda.

Michael Green
sumber
bahkan jika terbuka selama tiga hari?
JanLeeYu
Ya, bahkan selama tiga hari. Poin penting adalah jumlah pekerjaan yang telah dilakukan saat TX terbuka, bukan hanya berapa lama terbuka. Tentu saja sebagai DBA Anda mungkin ingin bertanya kepada pemilik transaksi mengapa mereka membutuhkannya terbuka begitu lama. Ketika saya menjalankan tim DBA saya login semua TX yang telah terbuka selama lebih dari 30 menit dan melakukan percakapan dengan pemilik.
Michael Green
BAIK. Terima kasih atas penjelasannya. Padahal semua orang juga hebat.
JanLeeYu
Lega sekali ... Terima kasih sekali lagi untuk jawabannya.
JanLeeYu
"UPDATE berkode buruk" Yup. Lihat ini. Pernyataan pembaruan di dalam loop yang tidak memenuhi syarat beberapa nama dan menghasilkan perilaku seperti 1 = 1, sehingga memperbarui seluruh tabel untuk setiap iterasi dari loop (yang juga menempatkan data yang salah pada sebagian besar baris itu juga).
jpmc26
6

Konsekuensi terbesar Anda adalah pemblokiran objek yang digunakan dalam transaksi. Terutama jika Anda menganggap pengguna Anda memasukkan data, maka transaksi jangka panjang itu bisa menyertakan pernyataan SELECT pada tabel yang umum digunakan. Pernyataan pembaruan pengguna Anda mungkin tidak bisa mendapatkan kunci yang diperlukan untuk menyelesaikan pembaruan atau sisipan mereka.

Hal sekunder yang dapat terjadi adalah aktivitas file log, katakanlah jika Anda memperbarui dataset besar, bagian dari log yang digunakan transaksi tetap aktif selama durasi transaksi itu. Anda tidak akan dapat menggunakan kembali bagian log sampai transaksi dilakukan atau dibatalkan. Dalam skenario di mana Anda berada dalam sistem OLTP yang sangat aktif, ini dapat menyebabkan file log Anda tumbuh dengan cepat, mengisi perangkat penyimpanan Anda.

Andriy M
sumber
misalnya orang yang membuat transaksi terputus dari server, apakah dia dapat masuk kembali ke server lagi untuk menutup transaksi?
JanLeeYu
Itu akan tergantung, jika transaksi itu dalam lingkungan yang menggunakan MSDTC itu bisa menjadi transaksi yatim piatu. Dalam hal itu, tidak ada pengguna yang tidak lagi dapat menutupnya sendiri ... DBA harus turun tangan untuk menanganinya. Di luar itu, Anda umumnya harus melihat transaksi dibatalkan oleh SQL Server ketika terputus ... tetapi sekali lagi pada transaksi besar yang mungkin tidak terjadi setiap saat.
Jika itu terjadi, apakah admin masih dapat menutup transaksi, bukan?
JanLeeYu
Saya tidak bisa menjawab yang itu, semuanya tergantung. Saya punya kasus di mana server harus direstart, atau instance gagal ke node / replika sekunder.
4

Transaksi yang tidak lengkap dapat menampung banyak kunci dan menyebabkan pemblokiran

Ketika suatu transaksi tidak selesai baik karena permintaan habis atau karena bets dibatalkan di tengah-tengah transaksi tanpa mengeluarkan pernyataan COMMIT atau ROLLBACK untuk menyelesaikan transaksi, transaksi dibiarkan terbuka dan semua kunci yang diperoleh selama transaksi berlanjut yang akan diadakan. Transaksi selanjutnya yang dieksekusi di bawah koneksi yang sama diperlakukan sebagai transaksi bersarang, sehingga semua kunci yang diperoleh dalam transaksi yang diselesaikan ini tidak dirilis. Masalah ini berulang dengan semua transaksi yang dilakukan dari koneksi yang sama sampai ROLLBACK dieksekusi. Akibatnya, sejumlah besar kunci ditahan, pengguna diblokir, dan transaksi hilang, yang menghasilkan data yang berbeda dari yang Anda harapkan.

sumber

Pimp Juice
sumber
misalnya orang yang membuat transaksi terputus dari server, apakah dia dapat masuk kembali ke server lagi untuk menutup transaksi?
JanLeeYu
Setelah SQL Server tahu koneksi telah hilang itu akan memutar kembali transaksi. Lihat di sini dba.stackexchange.com/questions/47404/… . Jika pengguna yang sama menghubungkan kembali itu akan menjadi sesi yang berbeda sehingga tidak bisa "mengadopsi" transaksi lama.
Michael Green