Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

किसी अन्य सत्र द्वारा उपयोग किए जाने वाले लेन-देन प्रसंग का कारण क्या है

उत्तर के लिए थोड़ा देर हो चुकी है :) लेकिन आशा है कि यह दूसरों के लिए उपयोगी होगा। उत्तर में तीन भाग होते हैं:

  1. इसका क्या अर्थ है "किसी अन्य सत्र में लेन-देन प्रसंग का उपयोग किया जा रहा है।"
  2. त्रुटि कैसे पुन:उत्पन्न करें "किसी अन्य सत्र द्वारा उपयोग में लेन-देन प्रसंग।"

<मजबूत>1. इसका क्या अर्थ है "किसी अन्य सत्र में लेन-देन प्रसंग का उपयोग किया जा रहा है।"

महत्वपूर्ण सूचना:लेन-देन संदर्भ लॉक को SqlConnection . के बीच बातचीत के ठीक पहले और तुरंत बाद जारी किया जाता है और एसक्यूएल सर्वर।

जब आप कुछ SQL क्वेरी निष्पादित करते हैं, SqlConnection "दिखता है" क्या इसे लपेटने वाला कोई लेनदेन है। यह SqlTransaction हो सकता है (एसक्यूएलकनेक्शन के लिए "मूल") या Transaction System.Transactions . से सभा।

जब लेन-देन पाया गया SqlConnection SQL सर्वर के साथ संचार करने के लिए इसका उपयोग करता है और फिलहाल वे Transaction communicate प्रसंग विशेष रूप से बंद है।

TransactionScope क्या करता है? ? यह Transaction बनाता है और इसके बारे में .NET Framework Components जानकारी प्रदान करता है, इसलिए SqlConnection सहित हर कोई (और डिज़ाइन द्वारा) इसका उपयोग कर सकता है।

तो TransactionScope घोषित करना हम नया लेनदेन बना रहे हैं जो वर्तमान Thread में तत्काल सभी "लेन-देन योग्य" वस्तुओं के लिए उपलब्ध है ।

वर्णित त्रुटि का अर्थ निम्न है:

  1. हमने कई SqlConnections बनाए हैं उसी के अंतर्गत TransactionContext (जिसका अर्थ है कि वे एक ही लेन-देन से संबंधित हैं)
  2. हमने ये SqlConnection के बारे में पूछा SQL सर्वर के साथ एक साथ संचार करने के लिए
  3. उनमें से एक ने मौजूदा Transaction को लॉक कर दिया है संदर्भ और अगली एक फेंकी गई त्रुटि

<मजबूत>2. त्रुटि कैसे पुन:उत्पन्न करें "किसी अन्य सत्र द्वारा उपयोग में लेन-देन प्रसंग।"

सबसे पहले, लेन-देन के संदर्भ का उपयोग ("लॉक") sql कमांड निष्पादन के समय किया जाता है। इसलिए निश्चित रूप से इस तरह के व्यवहार को पुन:पेश करना मुश्किल है।

लेकिन हम एकल लेनदेन के तहत अपेक्षाकृत लंबे SQL संचालन चलाने वाले कई थ्रेड शुरू करके इसे करने का प्रयास कर सकते हैं। आइए तालिका तैयार करें [dbo].[Persons] [tests] . में डेटाबेस:

USE [tests]
GO
DROP TABLE [dbo].[Persons]
GO
CREATE TABLE [dbo].[Persons](
    [Id] [bigint] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [Name] [nvarchar](1024) NOT NULL,
    [Nick] [nvarchar](1024) NOT NULL,
    [Email] [nvarchar](1024) NOT NULL)
GO
DECLARE @Counter INT
SET @Counter = 500

WHILE (@Counter > 0) BEGIN
    INSERT [dbo].[Persons] ([Name], [Nick], [Email])
    VALUES ('Sheev Palpatine', 'DarthSidious', '[email protected]')
    SET @Counter = @Counter - 1
END
GO

और "किसी अन्य सत्र द्वारा उपयोग में लेन-देन संदर्भ" को पुन:पेश करें। श्रीके कोड उदाहरण के आधार पर C# कोड में त्रुटि

using System;
using System.Collections.Generic;
using System.Threading;
using System.Transactions;
using System.Data.SqlClient;

namespace SO.SQL.Transactions
{
    public static class TxContextInUseRepro
    {
        const int Iterations = 100;
        const int ThreadCount = 10;
        const int MaxThreadSleep = 50;
        const string ConnectionString = "Initial Catalog=tests;Data Source=.;" +
                                        "User ID=testUser;PWD=Qwerty12;";
        static readonly Random Rnd = new Random();
        public static void Main()
        {
            var txOptions = new TransactionOptions();
            txOptions.IsolationLevel = IsolationLevel.ReadCommitted;
            using (var ctx = new TransactionScope(
                TransactionScopeOption.Required, txOptions))
            {
                var current = Transaction.Current;
                DependentTransaction dtx = current.DependentClone(
                    DependentCloneOption.BlockCommitUntilComplete);               
                for (int i = 0; i < Iterations; i++)
                {
                    // make the transaction distributed
                    using (SqlConnection con1 = new SqlConnection(ConnectionString))
                    using (SqlConnection con2 = new SqlConnection(ConnectionString))
                    {
                        con1.Open();
                        con2.Open();
                    }

                    var threads = new List<Thread>();
                    for (int j = 0; j < ThreadCount; j++)
                    {
                        Thread t1 = new Thread(o => WorkCallback(dtx));
                        threads.Add(t1);
                        t1.Start();
                    }

                    for (int j = 0; j < ThreadCount; j++)
                        threads[j].Join();
                }
                dtx.Complete();
                ctx.Complete();
            }
        }

        private static void WorkCallback(DependentTransaction dtx)
        {
            using (var txScope1 = new TransactionScope(dtx))
            {
                using (SqlConnection con2 = new SqlConnection(ConnectionString))
                {
                    Thread.Sleep(Rnd.Next(MaxThreadSleep));
                    con2.Open();
                    using (var cmd = new SqlCommand("SELECT * FROM [dbo].[Persons]", con2))
                    using (cmd.ExecuteReader()) { } // simply recieve data
                }
                txScope1.Complete();
            }
        }
    }
}

और अंत में आपके आवेदन में लेनदेन समर्थन को लागू करने के बारे में कुछ शब्द:

  • यदि संभव हो तो बहु-थ्रेडेड डेटा संचालन से बचें (चाहे लोड हो रहा हो या सहेजा जा रहा हो)। उदा. सहेजें SELECT /UPDATE / etc... एक ही कतार में अनुरोध करता है और एकल-थ्रेड कार्यकर्ता के साथ उनकी सेवा करता है;
  • मल्टी-थ्रेडेड एप्लिकेशन में लेनदेन का उपयोग करते हैं। हमेशा। हर जगह। पढ़ने के लिए भी;
  • एक से अधिक थ्रेड के बीच एकल लेनदेन साझा न करें। यह अजीब, स्पष्ट, अनुवांशिक और प्रतिलिपि प्रस्तुत करने योग्य नहीं . का कारण बनता है त्रुटि संदेश:
    • "किसी अन्य सत्र द्वारा उपयोग में लेन-देन प्रसंग।":एक लेन-देन के तहत सर्वर के साथ एक साथ कई इंटरैक्शन;
    • "टाइमआउट समाप्त हो गया है। ऑपरेशन पूरा होने से पहले समय समाप्त हो गया है या सर्वर प्रतिक्रिया नहीं दे रहा है।":निर्भर लेनदेन पूरा नहीं हुआ;
    • "लेन-देन संदेह में है";
    • ... और मैं बहुत कुछ मानता हूं ...
  • TransactionScope . के लिए आइसोलेशन लेवल सेट करना न भूलें . डिफ़ॉल्ट Serializable है लेकिन ज्यादातर मामलों में ReadCommitted काफी है;
  • पूर्ण करना न भूलें() TransactionScope और DependentTransaction


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. SQL सर्वर डेटाबेस में सभी तालिकाओं में पहचान कॉलम में प्राथमिक कुंजी बाधा कैसे जोड़ें - SQL सर्वर / TSQL ट्यूटोरियल भाग 63

  2. SQL सर्वर का उपयोग कैसे करें ऑलवेजऑन फीचर्स

  3. आप Microsoft SQL सर्वर में अनुक्रम कैसे लागू करेंगे?

  4. कनेक्शनस्ट्रिंग गुण VB.NET में त्रुटि प्रारंभ नहीं किया गया है

  5. टी-एसक्यूएल का उपयोग करके "सर्वर आरपीसी के लिए कॉन्फ़िगर नहीं किया गया है" संदेश 7411 को कैसे ठीक करें?