Apa yang terjadi jika Anda tidak melakukan transaksi ke database (misalnya, SQL Server)?

108

Misalkan saya memiliki pertanyaan:

begin tran
-- some other sql code

Dan kemudian saya lupa untuk berkomitmen atau memutar kembali.

Jika klien lain mencoba menjalankan kueri, apa yang akan terjadi?

Charbel
sumber

Jawaban:

148

Selama Anda tidak BERKOMIT atau ROLLBACK , transaksi masih "berjalan" dan berpotensi memiliki kunci.

Jika klien Anda (aplikasi atau pengguna) menutup koneksi ke database sebelum melakukan, setiap transaksi yang masih berjalan akan dibatalkan dan diakhiri.

marc_s
sumber
1
mmm, ok saya pikir ini menciptakan semacam kunci. Saya tidak yakin bahwa menutup koneksi akan benar-benar mengeluarkan saya dari kondisi ini. Masalahnya adalah saya mendapatkan kesalahan saat mencoba melakukan. sekarang saya menutup koneksi dan semuanya bekerja.
Charbel
12
Catatan tambahan: Jika menggunakan Management Studio, menutup jendela query akan menutup koneksi
Joe Phillips
3
@BradleyDotNET: ya, pasti
marc_s
2
Perlu diingat bahwa SQL Server Management Studio otomatis melakukan jika Anda menutup jendela / koneksi kueri, secara default.
Nuno
1
Perhatikan bahwa ketika klien menutup koneksi saat transaksi aktif, transaksi tidak selalu dibatalkan - ini tergantung pada klien dan db. Misalnya, saat aplikasi Java menutup koneksi ke Oracle db, koneksi terbuka apa pun akan otomatis dilakukan.
AviD
38

Anda benar-benar dapat mencobanya sendiri, yang akan membantu Anda mengetahui cara kerjanya.

Buka dua jendela (tab) di studio manajemen, masing-masing akan memiliki koneksi sendiri ke sql.

Sekarang Anda dapat memulai transaksi dalam satu jendela, melakukan beberapa hal seperti menyisipkan / memperbarui / menghapus, tetapi belum melakukan. lalu di jendela lain Anda dapat melihat tampilan database dari luar transaksi. Bergantung pada tingkat isolasi, tabel mungkin dikunci sampai jendela pertama dilakukan, atau Anda mungkin (tidak) melihat apa yang telah dilakukan transaksi lain sejauh ini, dll.

Bermain-main dengan tingkat isolasi yang berbeda dan tanpa petunjuk kunci untuk melihat bagaimana pengaruhnya terhadap hasil.

Lihat juga apa yang terjadi jika Anda melakukan kesalahan dalam transaksi.

Sangat penting untuk memahami bagaimana semua hal ini bekerja atau Anda akan bingung dengan apa yang dilakukan sql, sering kali.

Selamat bersenang-senang! GJ.

gjvdkamp.dll
sumber
ok tapi apakah transaksi akan ditulis ke log setidaknya sebelum mengeluarkan komit? Misalnya, saya ingin memulai transaksi, jalankan perintah sisipkan dan "lakukan sesuatu yang lain" sebelum saya menjalankan commit. akankah perintah insert saya ditulis ke log? dengan cara itu jika server crash sebelum mengeksekusi commit..it dapat kembali ke tempat semula dan saya dapat mengeluarkan commit nanti (setiap kali saya selesai melakukan "sesuatu yang lain").
pengguna1870400
16

Transaksi dimaksudkan untuk berjalan sepenuhnya atau tidak sama sekali. Satu-satunya cara untuk menyelesaikan transaksi adalah dengan berkomitmen, cara lain apa pun akan menghasilkan rollback.

Oleh karena itu, jika Anda memulai dan kemudian tidak melakukan, itu akan dibatalkan saat koneksi ditutup (karena transaksi terputus tanpa menandai sebagai selesai).

Piskvor meninggalkan gedung
sumber
Begitulah seharusnya, tetapi tidak selalu demikian.
FalcoGer
... seperti MyISAM mySQL, yang tidak mendukung transaksi, tentu.
Piskvor meninggalkan gedung
3

tergantung pada tingkat isolasi dari transaksi masuk.

Isolasi transaksi Sql dijelaskan

Xhalent
sumber
6
Perilaku transaksi tidak bergantung pada tingkat isolasi. Jumlah kunci yang mungkin mereka sebabkan tidak.
marc_s
Saya cukup yakin data apa yang dapat dibaca oleh suatu koneksi pasti bergantung pada tingkat isolasi. Jika Anda memiliki isolasi yang disetel ke BACA TIDAK DIKOMITASI, Anda dapat membaca data yang belum dikomit dan mungkin sebenarnya diputar kembali di beberapa titik trek, tetapi ini memastikan tidak ada penguncian. Jika Anda telah BACA BERKOMITMEN sebagai tingkat isolasi Anda, maka Anda tidak dapat membaca baris tanpa ikatan - klien kedua akan hang kecuali Anda menggunakan SNAPSHOT.
Xhalent
2

Saat Anda membuka transaksi, tidak ada yang terkunci dengan sendirinya. Tetapi jika Anda menjalankan beberapa kueri di dalam transaksi itu, bergantung pada tingkat isolasi, beberapa baris, tabel, atau halaman akan dikunci sehingga akan memengaruhi kueri lain yang mencoba mengaksesnya dari transaksi lain.

merah. semanggi
sumber
1

Contoh Transaksi

mulai tran tt

Pernyataan sql Anda

jika terjadi kesalahan rollback tran tt else commit tran tt

Selama Anda belum mengeksekusi tran tt komit, data tidak akan berubah

pengguna3386471
sumber
1
Perhatikan bahwa penamaan transaksi tidak hanya tidak diperlukan di MS SQL, tetapi juga dapat memberikan rasa kendali yang salah. BEGIN TRAN X ... BEGIN TRAN Y ... ROLLBACK Ytidak berfungsi, misalnya. Lihat stackoverflow.com/questions/1273376/…
0

Selain masalah penguncian potensial yang mungkin Anda sebabkan, Anda juga akan menemukan bahwa log transaksi Anda mulai tumbuh karena tidak dapat dipotong melewati LSN minimum untuk transaksi aktif dan jika Anda menggunakan isolasi snapshot, toko versi Anda di tempdb akan bertambah untuk alasan serupa.

Anda dapat menggunakan dbcc opentranuntuk melihat detail dari transaksi terbuka terlama.

Martin Smith
sumber
0

Setiap transaksi yang belum dilakukan akan membuat server terkunci dan kueri lain tidak akan dijalankan di server. Anda juga perlu mengembalikan transaksi atau melakukannya. Menutup SSMS juga akan menghentikan transaksi yang memungkinkan kueri lain untuk dieksekusi.

Josh Moorish
sumber
-4

Perilaku tidak ditentukan, jadi Anda harus secara eksplisit menyetel komit atau rollback:

http://docs.oracle.com/cd/B10500_01/java.920/a96654/basic.htm#1003303

"Jika mode komit otomatis dinonaktifkan dan Anda menutup koneksi tanpa secara eksplisit melakukan atau mengembalikan perubahan terakhir Anda, maka operasi COMMIT implisit dijalankan."

Hsqldb melakukan rollback

con.setAutoCommit(false);
stmt.executeUpdate("insert into USER values ('" +  insertedUserId + "','Anton','Alaf')");
con.close();

hasilnya adalah

2011-11-14 14: 20: 22.519 INFO utama [SqlAutoCommitExample: 55] [AutoCommit enabled = false] 2011-11-14 14: 20: 22.546 INFO utama [SqlAutoCommitExample: 65] [Ditemukan 0 # pengguna di database]

Bernd Schatz
sumber
2
Ini mungkin benar untuk Oracle (saya tidak tahu), tetapi penanya bertanya tentang MS-SQL
PaulG
Kutipan pertama berlaku untuk driver JDBC, bukan ke server.
djechlin