নোলকের সাথে সত্তা ফ্রেমওয়ার্ক


138

NOLOCKসত্তা ফ্রেমওয়ার্কে আমি কীভাবে এই ফাংশনটি ব্যবহার করতে পারি ? এক্সএমএল এটি করার একমাত্র উপায়?

উত্তর:


207

না, তবে আপনি কোনও লেনদেন শুরু করতে পারেন এবং নিরীক্ষণ করতে পড়ার জন্য বিচ্ছিন্নতা স্তর নির্ধারণ করতে পারেন । এটি মূলত NOLOCK হিসাবে একই কাজ করে, তবে এটি প্রতি টেবিলের ভিত্তিতে না করে বরং লেনদেনের আওতায় থাকা সমস্ত কিছুর জন্য এটি করবে।

যদি আপনি যা চান তা যদি মনে হয়, আপনি কীভাবে এটি চালিয়ে যেতে পারেন তা এখানে রয়েছে ...

//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();
}

দুর্দান্ত @ ডক্টা জোনেজ ​​এর জন্য ইএফ 4-তে নতুন কি কিছু চালু হয়েছিল?
এফএমএফএফ

@ এফএমএফএফ আমি জানি না ইএফ 4 এর জন্য নতুন কিছু চালু হয়েছিল কিনা। আমি জানি যে উপরের কোডটি EFv1 এবং তারপরে যদিও এর সাথে কাজ করে।
ডক্টর জোন্স

পরিণতি কি হবে? যদি উপরে বর্ণিত ব্লকটিতে কেউ লেনদেনস্কোপ.কম্পিউট (সম্পূর্ণ) বাদ দেয়? আপনি কি মনে করেন এর জন্য আমার আরও একটি প্রশ্ন করা উচিত?
একান গোপালকৃষ্ণন

@ একানগোপালকৃষ্ণন এই পদ্ধতিটিকে কল করতে ব্যর্থ হলেন এই লেনদেনকে বাতিল করে দেয়, কারণ লেনদেন পরিচালক এটিকে সিস্টেম ব্যর্থতা বা লেনদেনের ক্ষেত্রের মধ্যে ফেলে দেওয়া ব্যতিক্রম হিসাবে ব্যাখ্যা করে। (এমএসডিএন এমএসডিএন.মাইক্রোসফট. com/en-us/library/… থেকে নেওয়া )
ডাক্তার জোন্স

1
@ জসন স্ট্যাথাম এটি এই টান অনুরোধে যুক্ত করা হয়েছে , যা মাইলফলক ২.১.০ এর জন্য
ডক্টর জোন্স

83

এক্সটেনশন পদ্ধতিগুলি এটিকে আরও সহজ করে তুলতে পারে

public static List<T> ToListReadUncommitted<T>(this IQueryable<T> query)
{
    using (var scope = new TransactionScope(
        TransactionScopeOption.Required, 
        new TransactionOptions() { 
            IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
    {
        List<T> toReturn = query.ToList();
        scope.Complete();
        return toReturn;
    }
}

public static int CountReadUncommitted<T>(this IQueryable<T> query)
{
    using (var scope = new TransactionScope(
        TransactionScopeOption.Required, 
        new TransactionOptions() { 
            IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
    {
        int toReturn = query.Count();
        scope.Complete();
        return toReturn;
    }
}

আমার প্রকল্পে এটি ব্যবহারের ফলে সংযোগ পুলের সম্পূর্ণ ব্যবহার ব্যতীত ব্যতীত হবে। বুঝতে পারছিনা কেন। অন্য কেউ এই সমস্যা আছে? কোনও পরামর্শ?
বেন টিডম্যান

1
কোনও সমস্যা নেই বেন, সবসময় আপনার সংযোগ প্রসঙ্গটি নিষ্পত্তি করতে ভুলবেন না।
আলেকজান্দ্রে

কোনও সম্ভাব্য কারণ হিসাবে লেনদেনের সুযোগ বাদ দিতে ইস্যুকে সংকুচিত করতে সক্ষম হয়েছিল। ধন্যবাদ। আমার কনস্ট্রাক্টরে থাকা কিছু সংযোগ পুনরায় চেষ্টা করার জন্য আমার কিছু করার ছিল।
বেন টিডম্যান

আমি বিশ্বাস করি সুযোগটি ট্রানজেকশনস্কোপ
অপশন

@ আলেকজান্দ্রে আমি অন্য পাঠ্যকমিত লেনদেনের মধ্যে এটি করলে কী হবে? উদাহরণস্বরূপ, আমি ডেটা সংরক্ষণ শুরু করার জন্য একটি লেনদেন তৈরি করেছি তবে এখন আমি আরও ডেটা জিজ্ঞাসা করছি এবং তাই এর মধ্যে একটি রিডউনমাস্টেড ট্রানজেকশন তৈরি করছি? এই "সম্পূর্ণ" কল করা কি আমার বাহ্যিক লেনদেন সম্পূর্ণ করবে? দয়া করে পরামর্শ দিন :)
জেসন লোকি স্মিথ

27

আপনার যদি বৃহত্তর কিছু প্রয়োজন হয় তবে সর্বোত্তম উপায় যা আমরা খুঁজে পেয়েছি যা প্রকৃতপক্ষে প্রতিবার একটি লেনদেনকোপ শুরু করার চেয়ে কম অন্তর্নিহিত, এই সাধারণ কমান্ডটি চালিয়ে আপনি নিজের অবজেক্ট প্রসঙ্গটি তৈরি করার পরে কেবল আপনার সংযোগের উপর ডিফল্ট লেনদেনের বিচ্ছিন্নতা স্তর নির্ধারণ করতে পারেন:

this.context.ExecuteStoreCommand("SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;");

http://msdn.microsoft.com/en-us/library/aa259216(v=sql.80).aspx

এই কৌশলটির সাহায্যে আমরা একটি সাধারণ ইএফ সরবরাহকারী তৈরি করতে সক্ষম হয়েছি যা আমাদের জন্য প্রসঙ্গ তৈরি করে এবং প্রকৃতপক্ষে আমাদের সমস্ত প্রসঙ্গে প্রতিটি সময় এই কমান্ডটি চালায় যাতে আমরা সর্বদা ডিফল্টরূপে "পড়াশোনাবিহীন" থাকি।


2
একা লেনদেনের বিচ্ছিন্নতা স্তর নির্ধারণের কোনও প্রভাব নেই। এটির কোনও প্রভাব ফেলতে আপনাকে আসলে কোনও লেনদেনের মধ্যেই চলতে হবে। পড়াশুনাবিহীন রাজ্যগুলির জন্য এমএসডিএন ডকুমেন্টেশন Transactions running at the READ UNCOMMITTED level do not issue shared locks। এর থেকে বোঝা যায় যে সুবিধাটি পেতে আপনার অবশ্যই কোনও লেনদেনের মধ্যে চলছে। ( এমএসডিএন.মাইক্রোসফটকম /en-gb/library/ms173763.aspx থেকে নেওয়া )। আপনার পন্থাটি কম অনুপ্রবেশকারী হতে পারে তবে আপনি কোনও লেনদেন ব্যবহার না করলে এটি কোনও কিছুই অর্জন করতে পারে না।
ডক্টর জোন্স

3
এমএসডিএন ডকুমেন্টেশন বলে: "এসকিউএল সার্ভারের সাথে সংযোগ দ্বারা জারি করা লেনদেন-এসকিউএল বিবৃতিগুলির লকিং এবং সারি সংস্করণ আচরণ নিয়ন্ত্রণ করে s" এবং "উল্লেখ করে যে বিবৃতিগুলি সারিগুলি পড়তে পারে যা অন্যান্য লেনদেন দ্বারা সংশোধিত হয়েছে তবে এখনও প্রতিশ্রুতিবদ্ধ হয়নি।" আমি যে বিবৃতিটি লিখেছি তা প্রতিটি এসকিউএল স্টেটমেন্টকে প্রভাবিত করে, এটি কোনও লেনদেনের ভিতরে রয়েছে বা না। আমি অনলাইনে লোকদের সাথে বিরোধিতা করতে পছন্দ করি না তবে একটি বৃহত উত্পাদন পরিবেশে আমাদের এই বিবৃতিটি ব্যবহারের উপর ভিত্তি করে আপনি সে সম্পর্কে স্পষ্টতই ভুল। জিনিস ধরে না, তাদের চেষ্টা করুন!
ফ্র্যাঙ্ক. জার্মেইন

আমি তাদের চেষ্টা করেছি, আমরা একটি উচ্চ লোড পরিবেশ পেয়েছি যেখানে এই লেনদেনের জন্য কোনও স্কোপের মধ্যে কোয়েরি না করা (এবং একটি মিলের লেনদেন) একটি অচলাবস্থার ফলস্বরূপ। আমার পর্যবেক্ষণগুলি এসকিউএল 2005 সার্ভারে করা হয়েছিল, সুতরাং আচরণের পরে কোনও পরিবর্তন হয়েছে কিনা তা আমি জানি না। আমি তাই সুপারিশ চাই; আপনি যদি কোনও পাঠ্যহীন বিচ্ছিন্নতা স্তর নির্দিষ্ট করে থাকেন তবে অচলাবস্থার অভিজ্ঞতা অবিরত রাখে, আপনার প্রশ্নগুলি কোনও লেনদেনের মধ্যে রাখার চেষ্টা করুন। আপনি যদি কোনও লেনদেন না তৈরি করে ডেডলকগুলি না পান তবে পর্যাপ্ত পরিমাণে।
ডক্টর জোন্স

3
@ ডক্টরজোনস - মাইক্রোসফ্ট এসকিউএল সার্ভারের সাথে সম্পর্কিত, সমস্ত প্রশ্নগুলি সহজাতভাবে লেনদেন হয়। একটি সুস্পষ্ট লেনদেন নির্দিষ্ট করে দেওয়া কেবল একই লেনদেনে 2 বা ততোধিক বক্তব্যকে গোষ্ঠীকরণের একটি মাধ্যম যাতে তারা কাজের একটি পারমাণবিক ইউনিট হিসাবে বিবেচিত হতে পারে। SET TRANSACTION ISOLATION LEVEL...কমান্ড একটি সংযোগ-স্তরের সম্পত্তি প্রভাবিত করে এবং যদি না একটি ক্যোয়ারী ইঙ্গিতটি দ্বারা অধিলিখিত অত: পর, সমস্ত এসকিউএল সেই মুহূর্তের পর (যে সংযোগের জন্য) থেকে বিবৃতি প্রভাবিত করে। এই আচরণটি কমপক্ষে এসকিউএল সার্ভার 2000 সাল থেকে এবং সম্ভবত এর আগে থেকেই হয়েছিল।
সলোমন রুটজকি

5
@DoctorJones - পরীক্ষা করে দেখুন: msdn.microsoft.com/en-us/library/ms173763.aspx । এখানে একটি পরীক্ষা। SSMS, একটি কোয়েরি (# 1) এবং রান খুলুন CREATE TABLE ##Test(Col1 INT); BEGIN TRAN; SELECT * FROM ##Test WITH (TABLOCK, XLOCK);। এক প্রশ্নের (# 2) এবং রান খুলুন: SELECT * FROM ##Test;। নির্বাচনটি টিবি # 1 এ এখনও খোলা লেনদেনের দ্বারা অবরুদ্ধ করা হওয়ায় নির্বাচনটি ফিরে আসবে না যা একচেটিয়া লক ব্যবহার করছে। # 2 এ নির্বাচন বাতিল করুন। SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTEDট্যাব # 2 এ একবার চালান । ট্যাব # 2 এ আবার নির্বাচন করুন এবং এটি ফিরে আসবে। ROLLBACKট্যাব # 1 এ চালানোর বিষয়ে নিশ্চিত হন ।
সলোমন রুটজকি

21

যদিও আমি একেবারে সম্মত হয়েছি যে রিড আনমনমিটেড লেনদেনের বিচ্ছিন্নতা স্তরটি ব্যবহার করা সেরা পছন্দ, তবে কিছু সময় আপনি ম্যানেজার বা ক্লায়েন্টের অনুরোধে NOLOCK ইঙ্গিত ব্যবহার করতে বাধ্য হন এবং এই স্বীকৃত হওয়ার বিরুদ্ধে কোনও কারণ নেই।

সত্তা ফ্রেমওয়ার্ক 6 এর মাধ্যমে আপনি নিজের ডিবিকম্যান্ডইন্টারসেপ্টারটি এর মতো প্রয়োগ করতে পারেন:

public class NoLockInterceptor : DbCommandInterceptor
{
    private static readonly Regex _tableAliasRegex = 
        new Regex(@"(?<tableAlias>AS \[Extent\d+\](?! WITH \(NOLOCK\)))", 
            RegexOptions.Multiline | RegexOptions.IgnoreCase);

    [ThreadStatic]
    public static bool SuppressNoLock;

    public override void ScalarExecuting(DbCommand command, 
        DbCommandInterceptionContext<object> interceptionContext)
    {
        if (!SuppressNoLock)
        {
            command.CommandText = 
                _tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (NOLOCK)");
        }
    }

    public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
    {
        if (!SuppressNoLock)
        {
            command.CommandText = 
                _tableAliasRegex.Replace(command.CommandText, "${tableAlias} WITH (NOLOCK)");
        }
    }
}

এই শ্রেণীর জায়গায়, আপনি আবেদন শুরুতে এটি প্রয়োগ করতে পারেন:

DbInterception.Add(new NoLockInterceptor());

এবং শর্তাধীনভাবে NOLOCKবর্তমান থ্রেডের অনুসন্ধানগুলিতে ইঙ্গিত যুক্ত করা বন্ধ করুন :

NoLockInterceptor.SuppressNoLock = true;

আমি এই সমাধানটি পছন্দ করি যদিও আমি রেজিটাকে কিছুটা পরিবর্তন করেছি:
রাশ

2
(? <tableAlias>] এএসটি [এক্সটেন্ডেন্ট \ ডি +] (? (নলোক)) দিয়ে) উদ্ভূত টেবিলের নলক সংযোজন রোধ করার জন্য যা কোনও ত্রুটির কারণ হয়। :)
রাশি

থ্রেড স্তরে সাপ্রেসনলক সেট করা একটি সুবিধাজনক উপায়, তবে বুলিয়ানটি আনসেট করা ভুলে যাওয়া সহজ, আপনার এমন একটি ফাংশন ব্যবহার করা উচিত যা আইডিজোপেসেবল ফিরিয়ে দেয়, নিষ্পত্তি পদ্ধতিটি পুনরায় মিথ্যাটিকে মিথ্যাতে সেট করতে পারে। এছাড়াও, থ্রেডস্ট্যাটিক async / প্রতীক্ষার সাথে সত্যই সামঞ্জস্যপূর্ণ নয়: stackoverflow.com/questions/13010563/…
জাপ

অথবা, আপনি যদি বিচ্ছিন্ন স্তরটি ব্যবহার করতে চান: 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); }
আদি

এটি ডাটাবেস ফাংশনগুলিতে অলোক সংযোজন করছে। কিভাবে ফাংশন জন্য এড়ানো?
ইভান লুইস

9

উপর উন্নত ডক্টর জোন্স 'র গৃহীত উত্তর এবং ব্যবহার PostSharp ;

প্রথম " ReadUncommitedTransactionSopopeAttribute "

[Serializable]
public class ReadUncommitedTransactionScopeAttribute : MethodInterceptionAspect
{
    public override void OnInvoke(MethodInterceptionArgs args)
    {
        //declare the transaction options
        var transactionOptions = new TransactionOptions();
        //set it to read uncommited
        transactionOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
        //create the transaction scope, passing our options in
        using (var transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
        {
            //declare our context
            using (var scope = new TransactionScope())
            {
                args.Proceed();
                scope.Complete();
            }
        }
    }
}

তারপরে যখনই আপনার এটির প্রয়োজন হবে,

    [ReadUncommitedTransactionScope()]
    public static SomeEntities[] GetSomeEntities()
    {
        using (var context = new MyEntityConnection())
        {
            //any reads we do here will also read uncomitted data
            //...
            //...

        }
    }

ইন্টারসেপ্টারের সাথে "NOLOCK" যুক্ত করতে সক্ষম হওয়া খুব ভাল তবে ওরাকলের মতো অন্যান্য ডাটাবেস সিস্টেমে সংযোগ করার সময় কাজ করবে না।


6

এটিকে ঘিরে ধরতে আমি ডাটাবেসে একটি ভিউ তৈরি করি এবং ভিউয়ের ক্যোয়ারিতে নোলক প্রয়োগ করি। আমি তখন ভিএফটিকে ইএফের মধ্যে একটি টেবিল হিসাবে দেখি।


4

EF6 প্রবর্তনের সাথে সাথে মাইক্রোসফ্ট বিগিনট্রান্সজেকশন () পদ্ধতি ব্যবহার করার পরামর্শ দেয়।

আপনি ইএফ 6 + এবং ইএফ কোরে লেনদেনের পরিবর্তে বিগ্রেট ট্রান্সজেকশন ব্যবহার করতে পারেন

using (var ctx = new ContractDbContext())
using (var transaction = ctx.Database.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted))
{
    //any reads we do here will also read uncommitted data
}

2

না, সত্যই নয় - সত্তা ফ্রেমওয়ার্কটি মূলত আপনার আসল ডাটাবেসের উপরে একটি বেশ কড়া স্তর। আপনার প্রশ্নগুলি ইএসকিউএল - সত্তা এসকিউএল - যা আপনার সত্তার মডেলটির দিকে প্রথম লক্ষ্যযুক্ত, এবং যেহেতু ইএফ একাধিক ডাটাবেস ব্যাকেন্ডকে সমর্থন করে তাই আপনি সরাসরি "নেটিভ" এসকিউএল সরাসরি আপনার ব্যাকএন্ডে প্রেরণ করতে পারবেন না ulated

নোকল ক্যোয়ারী ইঙ্গিতটি একটি এসকিউএল সার্ভার নির্দিষ্ট জিনিস এবং এটি অন্য কোনও সমর্থিত ডাটাবেসগুলিতে কাজ করবে না (যদি না তারা একই ইঙ্গিতটি প্রয়োগ করে - তবে আমি দৃ strongly়ভাবে সন্দেহ করি)।

আঙ্গুরের ছিরড়া


এই উত্তরটি পুরানো - আপনি অন্যরা যেমন উল্লেখ করেছেন তেমন NOLOCK ব্যবহার করতে পারেন এবং আপনি "নেটিভ" এসকিউএল ব্যবহার করতে পারেন Database.ExecuteSqlCommand()বা ব্যবহার করে DbSet<T>.SqlQuery()
ডান্ক

1
@ ডানক: ডাউনভোটের জন্য ধন্যবাদ - বিটিডব্লিউ: আপনাকে যেভাবেই ব্যবহার করা উচিত নয়(NOLOCK) - খারাপ অভ্যাসগুলি লাথি মারার জন্য দেখুন - সর্বত্র নোলক লাগানো - এটি সর্বত্র ব্যবহার করার জন্য প্রস্তাবিত নয় - একেবারে বিপরীত!
marc_s

0

একটি বিকল্প হ'ল একটি সঞ্চিত পদ্ধতি ব্যবহার করা (রায়ানের প্রস্তাবিত ভিউ সমাধানের অনুরূপ) এবং তারপরে EF থেকে সঞ্চিত পদ্ধতিটি কার্যকর করা। EF কেবল ফলাফলগুলি পাইপ করার সময় এইভাবে সঞ্চিত পদ্ধতিটি নোংরা পাঠ্য সম্পাদন করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.