क्या मैं एक उपयोगकर्ता परिभाषित तालिका प्रकार बना सकता हूं और उसी लेनदेन में इसका उपयोग कर सकता हूं?


13

जब मैं निम्नलिखित निष्पादित करता हूं (प्रबंधन स्टूडियो में, GO कमांड को बैचों में अलग कर देगा)

use tempdb

begin tran
go

CREATE TYPE dbo.IntIntSet AS TABLE(
    Value0 Int NOT NULL,
    Value1 Int NOT NULL
)
go

declare @myPK dbo.IntIntSet;
go

rollback

मुझे एक डेडलॉक त्रुटि संदेश मिलता है। मेरी प्रक्रिया खुद के साथ गतिरोध है। मैंने यह व्यवहार 2008, 2008R2 और 2012 में देखा है।

क्या मेरे नए बनाए गए प्रकार को उसी लेनदेन के अंदर उपयोग करने का एक तरीका है जो इसे बनाया गया था?


आप ऐसा लेनदेन के अंदर क्यों कर रहे हैं? क्या आप 'अस्थायी' यूडीटी की उम्मीद कर रहे हैं?
मैक्स वर्नोन

2
मुझे पता था कि मुझे यह सवाल मिलेगा। यह एक एकीकरण परीक्षण का हिस्सा है। एकीकरण परीक्षण ढांचा एक ही लेनदेन में सब कुछ करता है।
माइकल जे। स्वार्ट

1
परीक्षण को निष्पादित करने से पहले परीक्षण के लिए आवश्यक प्रकार बनाने के लिए एक स्पष्ट समाधान होगा। हालांकि, इससे आपको परीक्षण को स्वचालित करने में मदद नहीं मिलेगी।
मैक्स वर्नोन

@MichaelJSwart, क्या आप कुछ और विस्तृत कर सकते हैं, जिसे आप हासिल करने की कोशिश कर रहे हैं? तालिका प्रकार इतने प्रतिबंधक हैं, कि मैं यह नहीं देख सकता कि आप इसके साथ जा रहे हैं।
सेबास्टियन मीन

1
FYI करें मैं इस बारे में भी ब्लॉग sqlperformance.com/2013/11/t-sql-queries/single-tx-deadlock
हारून बर्ट्रेंड

जवाबों:


15

यह चार बार से कम नहीं रिपोर्ट किया गया है। यह एक तय के रूप में बंद था:

http://connect.microsoft.com/SQLServer/feedback/details/365876/

लेकिन यह सच नहीं था। (वर्कअराउंड सेक्शन को भी देखें - मैंने जो वर्कअराउंड सुझाया है वह हमेशा स्वीकार्य नहीं होगा।)

यह एक डिज़ाइन द्वारा बंद किया गया था / ठीक नहीं होगा:

http://connect.microsoft.com/SQLServer/feedback/details/581193/

ये दोनों नए और अभी भी सक्रिय हैं :

http://connect.microsoft.com/SQLServer/feedback/details/800919/ (अब इसे ठीक नहीं किया जाएगा )

http://connect.microsoft.com/SQLServer/feedback/details/804365/ (अब डिज़ाइन द्वारा बंद )

जब तक कि Microsoft को आश्वस्त नहीं किया जा सकता है, अन्यथा, आपको वर्कअराउंड ढूंढना होगा - बस आपके परीक्षण को चलाने से पहले सभी प्रकारों को तैनात किया जाना चाहिए, या इसे कई परीक्षणों में तोड़ना चाहिए।

मैं अपने संपर्कों से इस बात की पुष्टि करने की कोशिश करूंगा कि उमाचंदर का मतलब क्या था जो जल्द से जल्द तय किया गया था, क्योंकि जाहिर है कि बाद में बयानों में टकराव होता है।

अद्यतन # 1 (उम्मीद है, बिल्कुल 2)

मूल बग (जो निश्चित रूप से बंद था) में अन्य प्रकार शामिल थे, लेकिन प्रकार के नहीं TABLE। यह SQL सर्वर 2005 के खिलाफ बताया गया था, जिसमें स्पष्ट रूप से टेबल प्रकार और टीवीपी नहीं थे। ऐसा लगता है कि यूसी ने बताया कि गैर-टेबल उपनामों वाले बग को इस आधार पर तय किया गया था कि वे आंतरिक लेनदेन को कैसे संभालते हैं, लेकिन यह एक समान परिदृश्य को कवर नहीं करता है, जिसे बाद में टेबल प्रकारों के साथ पेश किया गया था। मैं अभी भी इस बात की पुष्टि पर इंतजार कर रहा हूं कि क्या उस मूल बग को कभी भी बंद किया जाना चाहिए था; मैंने सुझाव दिया है कि सभी को डिज़ाइन के अनुसार बंद किया जाए। यह आंशिक रूप से है क्योंकि यह एक तरह से है कि मैंने इसे काम करने की उम्मीद की थी, और आंशिक रूप से क्योंकि मुझे यूसी से यह समझ है कि इसे अलग तरीके से काम करने के लिए "फिक्सिंग" करना बेहद जटिल है, पिछड़े अनुकूलता को तोड़ सकता है, और एक उपयोगी होगा उपयोग के मामलों की बहुत सीमित संख्या। आपके या आपके उपयोग के मामले के खिलाफ कुछ भी नहीं, लेकिन परीक्षण परिदृश्यों के बाहर मैं '

अद्यतन # 2

मैंने इस मुद्दे के बारे में ब्लॉग किया है:

http://www.sqlperformance.com/2013/11/t-sql-queries/single-tx-deadlock


1

मैं इसे पुन: पेश करने में सक्षम था। गतिरोध ग्राफ काफी उत्सुक है:

<deadlock-list>
  <deadlock victim="process47f948">
    <process-list>
      <process id="process47f948" taskpriority="0" logused="0" waitresource="METADATA: database_id = 2 USER_TYPE(user_type_id = 257)" waittime="3607" ownerId="14873" transactionname="@myPK" lasttranstarted="2013-11-06T13:23:12.177" XDES="0x80f6d950" lockMode="Sch-S" schedulerid="1" kpid="2672" status="suspended" spid="54" sbid="0" ecid="0" priority="0" trancount="1" lastbatchstarted="2013-11-06T13:23:12.167" lastbatchcompleted="2013-11-06T13:23:12.163" clientapp="Microsoft SQL Server Management Studio - Query" hostname="xxxxx" hostpid="5276" loginname="xxxxx\xxxxx" isolationlevel="read committed (2)" xactid="14867" currentdb="2" lockTimeout="4294967295" clientoption1="671090784" clientoption2="390200">
        <executionStack>
          <frame procname="adhoc" line="2" sqlhandle="0x010002002d9fe3155066b380000000000000000000000000">
declare @myPK dbo.IntIntSet;     </frame>
        </executionStack>
        <inputbuf>

declare @myPK dbo.IntIntSet;
    </inputbuf>
      </process>
    </process-list>
    <resource-list>
      <metadatalock subresource="USER_TYPE" classid="user_type_id = 257" dbid="2" id="lock8009cc00" mode="Sch-M">
        <owner-list>
          <owner id="process47f948" mode="Sch-M" />
        </owner-list>
        <waiter-list>
          <waiter id="process47f948" mode="Sch-S" requestType="wait" />
        </waiter-list>
      </metadatalock>
    </resource-list>
  </deadlock>
</deadlock-list>

यह मुझे एक बग की तरह दिखता है और मैं आपको इसके लिए एक कनेक्ट आइटम खोलने की सलाह दूंगा।


अपनी तत्काल समस्या के बारे में जानने के लिए आप उपयोग कर सकते हैं tSQLt.NewConnection(मुझे लगता है कि आप tSQLt का उपयोग कर रहे हैं)

use tempdb

begin tran
go
EXEC tSQLt.NewConnection '
CREATE TYPE dbo.IntIntSet AS TABLE(
    Value0 Int NOT NULL,
    Value1 Int NOT NULL
)
';
go

declare @myPK dbo.IntIntSet;
go

rollback

मुझे अभी भी समझ नहीं आया कि मक्खी पर टेबल टाइप बनाने की आवश्यकता कहां से आ रही है और मुझे लगता है कि आप अपने परीक्षण को जटिल कर रहे हैं। यदि आप चर्चा करना चाहते हैं तो मुझे एक ईमेल भेजें।


2
आपकी मदद के लिए धन्यवाद सेबस्टियन। दुर्भाग्य से, मैं tSQLt का उपयोग नहीं कर रहा हूँ। आपको समझ में नहीं आता कि मक्खी पर एक प्रकार बनाने की आवश्यकता कहाँ से आती है क्योंकि मैंने इसे नहीं समझाया। मैं चीजों को कम नहीं कर रहा हूं, लेकिन मुझे इसे प्रदर्शित करने की आवश्यकता नहीं है।
माइकल जे। स्वार्ट

खैर, tSQLt.NewConnection कैसे लागू किया जाता है के tSQLt स्रोत कोड को देखें। यह काफी सीधा है और आपके ढांचे में भी काम करना चाहिए।
18ast में सेबस्टियन Meine

1
प्रकार बनाने का कोई भी प्रयास और फिर गतिरोध में समान लेनदेन परिणामों में इसका उपयोग करें (देखें मेरी बग रिपोर्ट, हारून के पोस्ट में लिंक - अंतिम लिंक); यह वर्कअराउंड काम नहीं करेगा (ठीक है, यह मानते हुए कि यह कुछ गूंगा नहीं करता है जैसे इनपुट स्टेटमेंट को निष्पादित करने से पहले एक खुला लेनदेन करें)।
जॉन सिगेल

-1

जब तक कोई व्यक्ति अलग-अलग नहीं जानता, मुझे नहीं लगता कि एकल लेनदेन में ऐसा करने का कोई तरीका है। मुझे नहीं लगता कि यह एक बग है।

प्रकार बनाते समय सबसे पहले, आपको एक स्कीमा संशोधन लॉक (Sch-M) लेना होगा। चूंकि आप लेन-देन नहीं करते हैं, इसलिए ताला खुला रहता है। फिर आप उसी प्रकार के लेन-देन को एक चर घोषित करने का प्रयास करते हैं। यह स्कीमा स्टेबिलिटी लॉक (Sch-S) लेने की कोशिश करता है। वे दो प्रकार एक ही वस्तु पर एक साथ असंगत हैं। चूंकि वे एक ही लेन-देन में हैं, इसलिए SQL इसे एक गतिरोध के रूप में मानता है क्योंकि जब लेनदेन खुला होता है तो Sch-S को कभी भी अनुमति नहीं दी जा सकती है।

प्रत्येक बैच को एक बार में चलाएं, और जैसे ही आप चर घोषित करने का प्रयास करते हैं, sysinos_tran_locks के खिलाफ चयन करें। आपको वही प्रक्रिया दिखाई देगी जो Sch-M को पकड़ेगी और उसी वस्तु पर Sch-S की प्रतीक्षा करेगी।


3
प्रकार असंगत हैं, लेकिन मैंने सोचा कि उसी प्रक्रिया को स्वयं इंतजार नहीं करना पड़ेगा। उदाहरण के लिए, मैं एक तालिका में एक स्तंभ जोड़ सकता हूं और फिर उसी लेनदेन में इसका उपयोग कर सकता हूं।
माइकल जे स्वार्ट

3
ताला प्रबंधक को यह पता लगाना चाहिए कि प्रक्रिया पहले से ही संसाधन पर (वास्तव में मजबूत) ताला पकड़े हुए है और प्रक्रिया को इंतजार नहीं करना चाहिए। आप पहले किसी पंक्ति को अपडेट कर सकते हैं और फिर उसे वापस भी पढ़ सकते हैं - वही स्थिति।
सेबस्टियन माइन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.