2009-04-20 29 views
30

में असिंक्रोनस ट्रिगर्स मेरे पास ट्रिगर हैं जो में बहुत सारे डेटा को कुशलतापूर्वक सम्मिलित करते हैं और प्रत्येक सम्मिलन, अद्यतन और हटाए जाने पर ऑडिट उद्देश्यों के लिए ट्रैकिंग तालिका बदलें।एसक्यूएल सर्वर 2005/2008

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

हालांकि में कुछ मामलों में जहां स्रोत तालिका एक बहुत कॉलम है, यह 30 सेकंड के लिए जो अस्वीकार्य है पूरा करने के लिए लेन-देन के लिए ले जा सकते हैं।

क्या ट्रिगर को असीमित रूप से चलाने का कोई तरीका है? कोई भी उदाहरण।

+0

बदलें ट्रैकिंग एक अंतर्निहित फीचर बीटीडब्ल्यू है :) https://msdn.microsoft.com/en-us/library/bb933874.aspx – moander

उत्तर

23

आप ट्रिगर को असीमित रूप से चला नहीं सकते हैं, लेकिन आप ट्रिगर को SQL Service Broker कतार में एक संदेश भेज सकते हैं। कतार को तब संग्रहीत प्रक्रिया द्वारा असीमित रूप से संसाधित किया जा सकता है।

+0

लेकिन फिर भी आप लेनदेन नियंत्रण तोड़ रहे हैं। – dkretz

+1

कोई भी जो वास्तव में सेवा ब्रोकर को समझता है वह बता सकता है कि ऊपर की टिप्पणी ("लेनदेन नियंत्रण तोड़ना") सच है? –

+2

लेनदेन को वापस करने या रोल करने के लिए, आपको तब तक इंतजार करना होगा जब तक कि सबकुछ सफल नहीं हो जाता है (प्रतिबद्ध करने के लिए), या कुछ विफल हो गया है (वापस रोल करने के लिए)। असिंक्रोनस का मतलब है कि आप बाकी तर्क को जारी रखने के लिए इसे समाप्त करने की प्रतीक्षा नहीं करते हैं। – dkretz

0

मुझे पता नहीं है, लेकिन क्या आप ऑडिट तालिका में मान डाल रहे हैं जो बेस टेबल में मौजूद है? यदि ऐसा है, तो आप केवल परिवर्तनों को ट्रैक करने पर विचार कर सकते हैं। इसलिए एक सम्मिलन परिवर्तन समय, उपयोगकर्ता, अतिरिक्त और एनयूएलएल का एक गुच्छा ट्रैक करेगा (असल में पहले मूल्य)। एक अपडेट में परिवर्तन समय, उपयोगकर्ता आदि और बदले गए कॉलम के पहले मान होंगे। एक डिलीट में इत्यादि और सभी मूल्यों में परिवर्तन होता है।

इसके अलावा, क्या आपके पास आधार तालिका प्रति ऑडिट तालिका या डीबी के लिए एक ऑडिट तालिका है? बेशक बाद में इंतजार कर सकते हैं क्योंकि प्रत्येक लेनदेन एक टेबल पर लिखने की कोशिश करता है।

1

मुझे आश्चर्य है अगर आप सहित जो परिवर्तन आदि आदि

फिर एक और प्रक्रिया के साथ आते हैं और डेटा के बाकी नकल कर सकता है किया एक "बहुत प्रक्रिया" तालिका में डालने से परिवर्तन ट्रैकिंग के लिए एक रिकॉर्ड टैग कर सकते नियमित रूप से।

2

स्पष्ट रूप से "इसकी नौकरी बहुत अच्छी तरह से" और "अस्वीकार्य" के बीच एक बुनियादी संघर्ष है।

यह मुझे लगता है कि आप एक ओओ प्रक्रियात्मक अनुप्रयोग में घटनाओं का उपयोग करने के समान ही ट्रिगर्स का उपयोग करने की कोशिश कर रहे हैं, जो IMHO मानचित्र नहीं करता है।

मैं किसी भी ट्रिगर तर्क को कॉल करता हूं जिसमें 30 सेकंड लगते हैं - नहीं, 0.1 सेकंड - अधिक निष्पादन के रूप में। मुझे लगता है कि आपको वास्तव में अपनी कार्यक्षमता को फिर से डिजाइन करने की आवश्यकता है और इसे किसी अन्य तरीके से करें। मैं कहूंगा "अगर आप इसे अतुल्यकालिक बनाना चाहते हैं", लेकिन मुझे नहीं लगता कि यह डिज़ाइन किसी भी रूप में समझ में आता है।

जहाँ तक "अतुल्यकालिक ट्रिगर" के रूप में, बुनियादी मौलिक संघर्ष है कि आप ऐसी बात के बीच TRAN शुरू और TRAN बयान COMMIT क्योंकि आप चाहे वह सफल रहा या नहीं का ट्रैक खो दिया है में शामिल हैं कभी नहीं हो सकता है।

+0

आपने ऊपर टिप्पणी की है कि सेवा ब्रोकर का उपयोग करके "अभी भी लेनदेन नियंत्रण तोड़ रहा है।" मैंने सेवा ब्रोकर का उपयोग नहीं किया है, लेकिन क्या यह लेनदेन नहीं होगा? –

+0

यह असीमित नहीं हो सकता है। लेनदेन में इसे नहीं रखा जा सकता है यदि आप यह जानने के लिए खत्म होने की प्रतीक्षा नहीं करते हैं कि यह सफल हुआ है या नहीं, यह जानने के लिए कि क्या चाबुक करना या रोल करना है या नहीं। – dkretz

+0

मैं दो वार्तालापों के बीच इस वार्तालाप को विभाजित करने के लिए क्षमा चाहता हूं। मुझे लगता है कि अगर एसबी अपनी कतार से रोलबैक की अनुमति दे सकता है, तो यह लेनदेन होगा। एक बार जब आप इसे कतार में लिख लेते हैं, तो आप इसे सफल मानते हैं। आप एक अच्छा मुद्दा बनाते हैं, लेकिन मैं इसे एक डिजाइन/परिभाषा के मुद्दे के रूप में देखता हूं (यह मानते हुए कि एसबी कतार में लिखना समग्र लेनदेन के हिस्से के रूप में वापस लाया जा सकता है)। –

0

मुझे संदेह है कि आपका ट्रिगर इन जेनेरिक सीएसवी/टेक्स्ट जेनरेटिंग ट्रिगरों में से एक है जो सभी तालिकाओं के लिए सभी जगहों के लिए सभी परिवर्तनों को लॉग इन करने के लिए डिज़ाइन किया गया है। सिद्धांत में अच्छा (शायद ...), लेकिन अभ्यास में बनाए रखने और उपयोग करने में मुश्किल है।

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

शायद आप ट्रिगर कार्य योजना लागू करके देखो और देखते हैं कि बिट सबसे लंबे समय तक ले जा रहा है हो सकता है?

क्या आप प्रति तालिका में ऑडिट, कहने के तरीके को बदल सकते हैं? आप वर्तमान लॉग डेटा को प्रासंगिक तालिकाओं में विभाजित कर सकते हैं।

1

इतिहास तालिका बनाएं। मुख्य तालिका को अद्यतन (/ हटाना/डालने) को अद्यतन करते समय, इतिहास तालिका में रिकॉर्ड के पुराने मान (ट्रिगर में हटाए गए छद्म-तालिका) डालें; कुछ अतिरिक्त जानकारी भी आवश्यक है (टाइमस्टैंप, ऑपरेशन प्रकार, शायद उपयोगकर्ता संदर्भ)। वैसे भी नए मूल्य लाइव टेबल में रखा जाता है।

इस तरह ट्रिगर्स तेजी से चलते हैं (एआर) और आप धीमी परिचालन को लॉग व्यूअर (प्रक्रिया) में स्थानांतरित कर सकते हैं।

2

SQL सर्वर 2014 एक बहुत ही दिलचस्प सुविधा Delayed Durability कहा जाता है की शुरुआत की। यदि आप एक विनाशकारी घटना के मामले में कुछ पंक्तियों को खोने को बर्दाश्त कर सकते हैं, जैसे सर्वर क्रैश, तो आप वास्तव में अपने प्रदर्शन जैसे शेन्ज़ोरियो में अपने प्रदर्शन को बढ़ा सकते हैं।

विलंबित लेनदेन स्थायित्व डिस्क पर लिखने के लिए एसिंक्रोनस लॉग का उपयोग करके पूरा किया जाता है। लेनदेन लॉग रिकॉर्ड एक बफर में रखा जाता है और डिस्क पर लिखा जाता है जब बफर भरता है या बफर फ्लशिंग ईवेंट स्थान लेता है। विलंबित लेनदेन स्थायित्व प्रणाली

तालिका युक्त डेटाबेस पहले देरी स्थायित्व अनुमति देने के लिए बदल दिया जाना चाहिए के भीतर दोनों विलंबता और विवाद कम कर देता है।

ALTER DATABASE dbname SET DELAYED_DURABILITY = ALLOWED 

फिर आप प्रति लेनदेन के आधार पर स्थायित्व को नियंत्रित कर सकते हैं।

begin tran 

insert into ChangeTrackingTable select * from inserted 

commit with(DELAYED_DURABILITY=ON) 

लेन-देन करता है, तो लेन-देन पार डेटाबेस है टिकाऊ के रूप में प्रतिबद्ध किया जाएगा, ताकि यह कार्य तभी अपने लेखा परीक्षा तालिका ट्रिगर के रूप में एक ही डेटाबेस में स्थित है काम करेंगे।

डाटाबेस को अनुमति के बजाए मजबूर करने की संभावना भी है। इससे डेटाबेस में सभी लेन-देन टिकाऊ हो जाते हैं।

ALTER DATABASE dbname SET DELAYED_DURABILITY = FORCED 

देरी स्थायित्व के लिए, वहाँ एक अप्रत्याशित बंद और एक उम्मीद बंद/एसक्यूएल सर्वर को फिर से प्रारंभ के बीच कोई अंतर नहीं है। आपदाजनक घटनाओं की तरह, आपको डेटा हानि की योजना बनाना चाहिए। एक योजनाबद्ध शटडाउन/डिस्क पर लिखे गए कुछ लेन-देन को पुन: प्रारंभ करें, पहले डिस्क पर सहेजा जा सकता है, लेकिन आपको इसकी योजना नहीं बनाना चाहिए। के रूप में योजना बनाएं, चाहे शट डाउन/रीस्टार्ट हो, चाहे योजनाबद्ध या अनियोजित हो, डेटा को आपदाजनक घटना के समान ही खो देता है।

इस अजीब दोष उम्मीद है कि एक भविष्य के रिलीज में संबोधित किया जाएगा, लेकिन तब तक यह स्वतः ही 'sp_flush_log' प्रक्रिया जब एसक्यूएल सर्वर को पुन: प्रारंभ या नीचे बंद है निष्पादित करने के लिए सुनिश्चित करने के लिए बुद्धिमान हो सकता है।

0

एसिंक्रोनस प्रोसेसिंग करने के लिए आप सेवा ब्रोकर का उपयोग कर सकते हैं, लेकिन यह एकमात्र विकल्प नहीं है, आप सीएलआर ऑब्जेक्ट्स का भी उपयोग कर सकते हैं।

using System; 
using System.Data; 
using System.Data.SqlClient; 
using System.Data.SqlTypes; 
using Microsoft.SqlServer.Server; 
using System.Runtime.Remoting.Messaging; 
using System.Diagnostics; 

public delegate void AsyncMethodCaller(string data, string server, string dbName); 

public partial class StoredProcedures 
{ 
    [Microsoft.SqlServer.Server.SqlProcedure] 
    public static void AsyncProcedure(SqlXml data) 
    { 
     AsyncMethodCaller methodCaller = new AsyncMethodCaller(ExecuteAsync); 
     string server = null; 
     string dbName = null; 
     using (SqlConnection cn = new SqlConnection("context connection=true")) 
     using (SqlCommand cmd = new SqlCommand("SELECT @@SERVERNAME AS [Server], DB_NAME() AS DbName", cn)) 
     { 
      cn.Open(); 
      using (SqlDataReader reader = cmd.ExecuteReader()) 
      { 
       reader.Read(); 
       server = reader.GetString(0); 
       dbName = reader.GetString(1); 
      } 
     } 
     methodCaller.BeginInvoke(data.Value, server, dbName, new AsyncCallback(Callback), null); 
     //methodCaller.BeginInvoke(data.Value, server, dbName, null, null); 
    } 

    private static void ExecuteAsync(string data, string server, string dbName) 
    { 
     string connectionString = string.Format("Data Source={0};Initial Catalog={1};Integrated Security=SSPI", server, dbName); 
     using (SqlConnection cn = new SqlConnection(connectionString)) 
     using (SqlCommand cmd = new SqlCommand("SyncProcedure", cn)) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add("@data", SqlDbType.Xml).Value = data; 
      cn.Open(); 
      cmd.ExecuteNonQuery(); 
     } 
    } 

    private static void Callback(IAsyncResult ar) 
    { 
     AsyncResult result = (AsyncResult)ar; 
     AsyncMethodCaller caller = (AsyncMethodCaller)result.AsyncDelegate; 
     try 
     { 
      caller.EndInvoke(ar); 
     } 
     catch (Exception ex) 
     { 
      // handle the exception 
      //Debug.WriteLine(ex.ToString()); 
     } 
    } 
} 

यह अतुल्यकालिक प्रतिनिधियों का उपयोग करता है कॉल करने के लिए SyncProcedure:

CREATE PROCEDURE SyncProcedure(@data xml) 
AS 
    INSERT INTO T(Data) VALUES (@data) 

बुला का उदाहरण

निम्नलिखित एक संग्रहीत प्रक्रिया (AsyncProcedure) का एक उदाहरण है कि अतुल्यकालिक एक और प्रक्रिया (SyncProcedure) कहता है AsyncProcedure:

EXEC dbo.AsyncProcedure N'<doc><id>1</id></doc>' 

दुर्भाग्य से, असेंबली को यूएनएसएएफई अनुमति की आवश्यकता है।

संबंधित मुद्दे