Tidak, tetapi Anda dapat memulai transaksi dan mengatur level isolasi untuk membaca tanpa komitmen . Ini pada dasarnya melakukan hal yang sama dengan NOLOCK, tetapi alih-alih melakukannya berdasarkan tabel, itu akan melakukannya untuk semua yang ada dalam ruang lingkup transaksi.
Jika itu terdengar seperti yang Anda inginkan, inilah cara Anda dapat melakukannya ...
//declare the transaction options
var transactionOptions = new System.Transactions.TransactionOptions();
//set it to read uncommited
transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;
//create the transaction scope, passing our options in
using (var transactionScope = new System.Transactions.TransactionScope(
System.Transactions.TransactionScopeOption.Required,
transactionOptions)
)
//declare our context
using (var context = new MyEntityConnection())
{
//any reads we do here will also read uncomitted data
//...
//...
//don't forget to complete the transaction scope
transactionScope.Complete();
}
Metode penyuluhan dapat membuat ini lebih mudah
sumber
Jika Anda memerlukan sesuatu yang luas, cara terbaik yang kami temukan yang tidak terlalu mengganggu daripada benar-benar memulai transaksi setiap kali, adalah dengan hanya mengatur tingkat isolasi transaksi default pada koneksi Anda setelah Anda membuat konteks objek Anda dengan menjalankan perintah sederhana ini:
http://msdn.microsoft.com/en-us/library/aa259216(v=sql.80).aspx
Dengan teknik ini, kami dapat membuat penyedia EF sederhana yang menciptakan konteks untuk kami dan benar-benar menjalankan perintah ini setiap kali untuk semua konteks kami sehingga kami selalu "membaca tanpa komitmen" secara default.
sumber
Transactions running at the READ UNCOMMITTED level do not issue shared locks
. Ini menyiratkan bahwa Anda harus menjalankan transaksi untuk mendapatkan manfaat. (diambil dari msdn.microsoft.com/en-gb/library/ms173763.aspx ). Pendekatan Anda mungkin tidak terlalu mengganggu, tetapi tidak akan mencapai apa pun jika Anda tidak menggunakan transaksi.SET TRANSACTION ISOLATION LEVEL...
perintah mempengaruhi properti koneksi-tingkat dan karenanya mempengaruhi semua pernyataan SQL yang dibuat dari saat itu (untuk koneksi YANG), kecuali diganti dengan petunjuk query. Perilaku ini telah ada sejak setidaknya SQL Server 2000, dan kemungkinan sebelumnya.CREATE TABLE ##Test(Col1 INT); BEGIN TRAN; SELECT * FROM ##Test WITH (TABLOCK, XLOCK);
. Buka permintaan lain (# 2) dan menjalankan:SELECT * FROM ##Test;
. SELECT tidak akan kembali karena diblokir oleh transaksi yang masih terbuka di tab # 1 yang menggunakan kunci eksklusif. Batalkan SELECT di # 2. JalankanSET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
sekali di tab # 2. Jalankan SELECT lagi di tab # 2 dan itu akan kembali. Pastikan dijalankanROLLBACK
di tab # 1.Meskipun saya benar-benar setuju bahwa menggunakan tingkat isolasi transaksi Read Uncommitted adalah pilihan terbaik, tetapi beberapa kali Anda dipaksa untuk menggunakan petunjuk NOLOCK atas permintaan manajer atau klien dan tidak ada alasan untuk menentang hal ini diterima.
Dengan Entity Framework 6 Anda dapat menerapkan DbCommandInterceptor sendiri seperti ini:
Dengan kelas ini tersedia, Anda dapat menerapkannya pada awal aplikasi:
Dan matikan menambahkan
NOLOCK
petunjuk ke permintaan untuk thread saat ini:sumber
public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) { if (!SuppressNoLock) command.CommandText = $"SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;{Environment.NewLine}{command.CommandText}"; base.ReaderExecuting(command, interceptionContext); }
Meningkatkan jawaban yang diterima Dokter Jones dan menggunakan PostSharp ;
Pertama " ReadUncommitedTransactionScopeAttribute "
Maka kapan pun Anda membutuhkannya,
Mampu menambahkan "NOLOCK" dengan interceptor juga bagus tetapi tidak akan berfungsi saat menghubungkan ke sistem database lain seperti Oracle.
sumber
Untuk mengatasinya, saya membuat tampilan pada database dan menerapkan NOLOCK pada permintaan tampilan. Saya kemudian memperlakukan tampilan sebagai tabel dalam EF.
sumber
Dengan diperkenalkannya EF6, Microsoft merekomendasikan untuk menggunakan metode BeginTransaction ().
Anda dapat menggunakan BeginTransaction alih-alih TransactionScope di EF6 + dan EF Core
sumber
Tidak, tidak juga - Kerangka Entitas pada dasarnya adalah lapisan yang cukup ketat di atas basis data Anda yang sebenarnya. Kueri Anda diformulasikan dalam ESQL - Entity SQL - yang pertama-tama ditargetkan untuk model entitas Anda, dan karena EF mendukung banyak database backend, Anda tidak dapat benar-benar mengirim SQL "asli" langsung ke backend Anda.
Petunjuk kueri NOLOCK adalah hal khusus SQL Server dan tidak akan berfungsi pada basis data yang didukung lainnya (kecuali jika mereka juga menerapkan petunjuk yang sama - yang sangat saya ragukan).
Marc
sumber
Database.ExecuteSqlCommand()
atauDbSet<T>.SqlQuery()
.(NOLOCK)
- lihat Kebiasaan Buruk untuk menendang - menempatkan NOLOCK di mana - mana - TIDAK DIREKOMENDASIKAN untuk menggunakan ini di mana-mana - justru sebaliknya!Salah satu opsi adalah menggunakan prosedur tersimpan (mirip dengan solusi tampilan yang diusulkan oleh Ryan) dan kemudian menjalankan prosedur tersimpan dari EF. Dengan cara ini prosedur yang tersimpan melakukan pembacaan kotor sementara EF hanya menyalurkan hasilnya.
sumber