<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlserver.ro/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Intrebari generale</title><link>http://sqlserver.ro/forums/16/ShowForum.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Varianta revizuita - cu stop (un fel de ...)</title><link>http://sqlserver.ro/forums/thread/5972.aspx</link><pubDate>Wed, 29 Oct 2008 12:24:41 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5972</guid><dc:creator>fgbogdan</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5972.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5972</wfw:commentRss><description>CREATE TRIGGER [TRIGGER_NAME] ON [dbo].[TBL_NAME]&lt;br /&gt;FOR INSERT, UPDATE, DELETE&lt;br /&gt;AS&lt;br /&gt;&lt;br /&gt;DECLARE @strAction AS VARCHAR(10)&lt;br /&gt;DECLARE @STRTABLENAME AS VARCHAR (100)&lt;br /&gt;DECLARE @STRCMD AS NVARCHAR (1000), @STRCMD1 AS NVARCHAR (1000)&lt;br /&gt;DECLARE @Column_Name  AS VARCHAR (50), @Type_Name AS VARCHAR (50)&lt;br /&gt;DECLARE @DeletedRows AS INT&lt;br /&gt;DECLARE @InsertedRows AS INT&lt;br /&gt;DECLARE @nIndex AS INT&lt;br /&gt;DECLARE @bContinue AS bit&lt;br /&gt;SET @bContinue = 0&lt;br /&gt;&lt;br /&gt;SELECT * INTO #inserted FROM inserted&lt;br /&gt;SET @InsertedRows = @@rowcount&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SELECT * INTO #deleted FROM deleted&lt;br /&gt;SET @DeletedRows = @@rowcount&lt;br /&gt;&lt;br /&gt;IF @InsertedRows &gt; 0&lt;br /&gt;BEGIN&lt;br /&gt;IF @DeletedRows &gt; 0&lt;br /&gt;	SET @strAction = 'UPDATE'&lt;br /&gt;ELSE&lt;br /&gt;	SET @strAction = 'INSERT'&lt;br /&gt;END&lt;br /&gt;ELSE&lt;br /&gt;BEGIN&lt;br /&gt;	SET @strAction = 'DELETE'&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;-- DELETE&lt;br /&gt;IF 'DELETE' = @strAction&lt;br /&gt;BEGIN &lt;br /&gt;	-- daca nu a mai fost apelat&lt;br /&gt;	IF ( (SELECT trigger_nestlevel(object_ID('TRIGGER_NAME')) ) &lt;br /&gt;	BEGIN&lt;br /&gt;		SET @STRCMD = ' delete from SRVREPL_NAME.DBREPL_NAME.dbo.TBL_NAME where ID_NAME in (select ID_NAME from #deleted)'&lt;br /&gt;		EXECUTE(@STRCMD)&lt;br /&gt;	END&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;-- daca este insert sau update ... determin daca sa merg mai departe ...&lt;br /&gt;-- si prelucrez &lt;br /&gt;IF 'INSERT' = @strAction OR 'UPDATE' = @strAction&lt;br /&gt;BEGIN &lt;br /&gt;&lt;br /&gt;	-- daca este insert sau update - determin care este valoarea lui SINCFIELD&lt;br /&gt;	DECLARE @SERVERNAME AS VARCHAR(20)&lt;br /&gt;	SELECT @SERVERNAME = SINCFIELD FROM #inserted&lt;br /&gt;&lt;br /&gt;	-- daca serverul din campul SINCFIELD este SRVREPL_NAME nu fac nimic&lt;br /&gt;	-- daca este NULL inseamna ca este prima data&lt;br /&gt;	-- daca e alt server ... merg mai departe&lt;br /&gt;	IF '['+@SERVERNAME+']' &lt;&gt; 'SRVREPL_NAME' OR @SERVERNAME IS NULL&lt;br /&gt;	BEGIN &lt;br /&gt;	&lt;br /&gt;		-- setez ca o sa fac insert sau update&lt;br /&gt;		SET @bContinue = 1&lt;br /&gt;		-- daca este null ... il initializez cu numele serverului meu&lt;br /&gt;		IF  @SERVERNAME IS NULL&lt;br /&gt;		BEGIN&lt;br /&gt;			UPDATE #inserted SET SINCFIELD = @@servername&lt;br /&gt;		END &lt;br /&gt;	END &lt;br /&gt;	-- daca SINCFIELD nu e NULL&lt;br /&gt;	IF NOT @SERVERNAME IS NULL &lt;br /&gt;	BEGIN &lt;br /&gt;		-- setez in tabela locala campul SINCFIELD pe null&lt;br /&gt;		UPDATE TBL_NAME SET SINCFIELD = NULL FROM TBL_NAME, #inserted WHERE TBL_NAME.ID_NAME = #inserted.ID_NAME&lt;br /&gt;	END &lt;br /&gt;	&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- INSERT&lt;br /&gt;IF 'INSERT' = @strAction AND @bContinue = 1&lt;br /&gt;BEGIN &lt;br /&gt;	-- inserez&lt;br /&gt;	SET @STRCMD = ' INSERT INTO SRVREPL_NAME.DBREPL_NAME.dbo.TBL_NAME select FIELDS_LIST from #inserted	'&lt;br /&gt;	EXECUTE(@STRCMD)&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;-- UPDATE&lt;br /&gt;IF 'UPDATE' = @strAction AND @bContinue = 1&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;	DECLARE @ColumnID int, @Columns nvarchar(4000), @ObjectID int, @LastColumnID int&lt;br /&gt;	&lt;br /&gt;	SET @ObjectID=(SELECT id FROM sysobjects WHERE name='TBL_NAME')&lt;br /&gt;	SET @LastColumnID=(SELECT MAX(colid) FROM syscolumns WHERE id=@ObjectID)&lt;br /&gt;	SET @ColumnID=1&lt;br /&gt;	WHILE @ColumnID&lt;br /&gt;		IF (SUBSTRING(COLUMNS_UPDATED(),(@ColumnID - 1) / 8 + 1, 1)) &amp;amp;&lt;br /&gt;		POWER(2, (@ColumnID - 1) % 8) = POWER(2, (@ColumnID - 1) % 8)&lt;br /&gt;		SET @Columns = ISNULL(@Columns+',','') + COL_NAME(@ObjectID,@ColumnID) + ' = #inserted.' + COL_NAME(@ObjectID,@ColumnID) + ' '&lt;br /&gt;		SET @ColumnID=@ColumnID+1&lt;br /&gt;	END &lt;br /&gt;	&lt;br /&gt;	-- trebuie sa trimit mai departe si SINCFIELD&lt;br /&gt;	SET @Columns = @Columns + ', SINCFIELD=#inserted.SINCFIELD '&lt;br /&gt;	-- trebuie sa inlocuiesc IN tabela tinta ... coloana @Column_Name&lt;br /&gt;	SET @STRCMD = 'UPDATE SRVREPL_NAME.DBREPL_NAME.dbo.TBL_NAME SET ' + @Columns + ' FROM SRVREPL_NAME.DBREPL_NAME.dbo.TBL_NAME C, #inserted WHERE C.ID_NAME = #inserted.ID_NAME'&lt;br /&gt;	EXECUTE(@STRCMD)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;END &lt;br /&gt;&lt;br /&gt;-- curatenie&lt;br /&gt;DROP TABLE #inserted&lt;br /&gt;DROP TABLE #DELETED&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;conditii ... fiecare tabela trebuie sa aiba campul SINCFIELD care sa accepte NULL si sa nu fie modificat din aplicatie.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;ideea e ca la primul apel ea vine null si apoi trece la urmatoarele servere cu numele serverului care a initiat actiunea.&lt;br /&gt;&lt;br /&gt;oricum pana la varianta finala care sa contina si offline mai e muuuuuuuuuuuuult ...</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5761.aspx</link><pubDate>Tue, 07 Oct 2008 05:37:22 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5761</guid><dc:creator>fgbogdan</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5761.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5761</wfw:commentRss><description>intradevar - pus pe hartie e mai avantajos cu mesh - insa ma gandeam ca conditia de oprire ar fi mai simplu de implementat la inel. (folosind eventual o coloana in tabela in care sa fie id-ul sau numele serverului care face update-ul original). &lt;br /&gt;Ca si la retele ... topologia in inel nu e mai avantajoasa - ci poate doar mai simpla pentru intelegerea umana. Vreau sa incerc inainte - si apoi o sa vad practic care imi este mai buna.</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5757.aspx</link><pubDate>Mon, 06 Oct 2008 18:14:13 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5757</guid><dc:creator>rremus</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5757.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5757</wfw:commentRss><description>Hai sa mai facem un pic de matematica.&lt;br&gt;&lt;br&gt;Sa consideram ca un update se executa intr-un timp T, sa zicem intr-o suta de milisecunde. Cind faci un update pe S1, batch-ul executa update apoi asteapta executia trigger-ului. Pe S2 se executa din nou in T, apoi S2 asteapta se se execute pe S3 s.a.m.d. Pe Sn dureaza 100 ms apoi se intoarce. Deci Sn a asteptat 100ms, Sn-1 200ms, pe Sn-2 300 ms s.a.m.d. Timpul total de consumat in sistem de executarea update-ului este suma acestor timpuri, deci N(N+1)/2 * T. A nu se confunda cu durata de executie al update-ului, care este evident T*N.&lt;br&gt;&lt;br&gt;In SQL Server exista o resursa foarte bine definita, anume numarul de 'worker threads'. Fiecare worker thread poate executa la un moment dat un singur batch (=request). Un worker nu poate abandona un batch pina ce nu il termina. Un bath care asteapta un raspuns de la un linked server este blocat, nu terminat, si consuma un worker. Numarul de worker threads este limitat. Hai sa consideram numarul implicit, 256 de worker threads. Cu acest numar putem determina limita absoluta, ideala, care ne spune cite write-uri putem face in sistem.&lt;br&gt;Cu 3 noduri ai la dispozitie 3*256 workere, care pot executa 7680 de taskuri de cite 100 ms fiecare. Un update in topologia 'inel' consuma 6 astfel de quate de cite 100 ms (1 pe S3, 2 pe S2 si 3 pe S1). Deci in conditzii ideale potzi sa obtzii 7680/6 = 1280 update-uri in sistem intr-o secunda. Cu 5 noduri, ai la dispozitzie 12800 de 'quante' si fiecare update consuma 15, deci potzi spera la 853 de scrieri pe secunda. Cu 20 de noduri ai nevoie de 210 'quante' pentru un update, rezultind un throughput de ~244 operatii pe secunda.&lt;br&gt;&lt;br&gt;Hai sa consideram topologia mesh, fiecare se conecteaza la fiecare. Un update in aceasta topologie consuma T pe S1, apoi S1 updateaza S2 (=T), apoi updateaza S3 (=T) s.am.d. Timpul total consumat pe toate nodurile este 2N-1 (S1 consuma T*N pentru ca sta sa updateze S2...SN si la asta se adauga N-1 pentru fiecare timp T consumat de S2...S3). Pe 3 noduri un update consuma 5 'quante' (3 pe S1, 1 pe S2, 1 pe S3). Deci potzi scrie 7680/5=1536 operatii, o imbunatarire cu 120% fata de topologia 'inel'.&amp;nbsp; Cu 5 noduri ai nevoie de 9 'quante' si obtii 1422 operatii pe secunda, cu 166% mai bine decit in inel. Cu 20 de noduri ai nevoie de 39 de 'quante' si potzi obtzine un throughput 1313 operatii, care este cu doar 538% mai bine decit in topologia 'inel'.&lt;br&gt;&lt;br&gt;Se vede de fapt ca numarul de 'worker' threads ales si durata unui update (T) sint irelevante, diferenta vine din formula de timp linear pentru mesh (2N-1) fata de timp patratic ( N(N+1)/2 ) pentru 'inel'. Asta in ciuda faptului ca timpul de 'raspuns' al fiecarui update este identic in ambele topologii (T*N). Dar intr-una din topologii (mesh) exista un singur nod care astepta pe celelate, in timp ce in 'inel' toate nodurile astepta nodurile 'de la dreapta', cu exceptia ultimului.&lt;br&gt;&lt;br&gt;Asa ca revin la intrebarea originala: care exact sint avantajele toplogiei in inel?&lt;br&gt;&lt;br&gt;</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5756.aspx</link><pubDate>Mon, 06 Oct 2008 17:40:14 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5756</guid><dc:creator>fgbogdan</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5756.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5756</wfw:commentRss><description>nuuuu, nu face disable, ca altfel nu poate sa mearga mai departe. Trebuie sa il lase sa "fire"-uie, Exemplul trimis de mine ste numai pentru 2 servere. Pentru varianta de "inel" trebuie sa gasesc o metoda de oprire - pe care inca nu o stiu. Eventual sa determin care e serverul pe care trebuie sa se opreasca triggerul meu (adica daca plec de pe S(N) ... triggerul sa numai "fire"-uie pe S(N-1).</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5755.aspx</link><pubDate>Mon, 06 Oct 2008 15:44:35 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5755</guid><dc:creator>rremus</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5755.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5755</wfw:commentRss><description>&lt;BLOCKQUOTE&gt;&lt;div&gt;&lt;img src="http://sqlserver.ro/Themes/default/images/icon-quote.gif"&gt; &lt;strong&gt;fgbogdan:&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;toate sunt after (update, insert, delete) ... ca sa nu fie blocaje. Daca reuseste sa faca update pe serverul urmator bine - daca nu logheaza si o sa faca cand o sa fie online (cu un job probabil). NU asteapta unii dupa altii ca atunci ajung la blocaje.&lt;/div&gt;&lt;/BLOCKQUOTE&gt;&lt;br&gt;&lt;br&gt;Am priceput, deci S1 face un update, triggerul lui S1 updateaze pe S2 dar face disable la trigger-ul de pe S2 innainte de update asa incit trigger-ul lui S2 nu se activeaza. Acuma update-ul a ajuns la S2. Cum ajunge update-ul lui S1 la S3?&lt;br&gt;&lt;br&gt;Ignoram pentru moment faptul ca ALTER TABLE cere un lock Sch-M pe tabela, blocind toate operatziile care cer Sch-S (cum ar fi SELECT).&lt;br&gt;</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5754.aspx</link><pubDate>Mon, 06 Oct 2008 15:37:34 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5754</guid><dc:creator>fgbogdan</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5754.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5754</wfw:commentRss><description>toate sunt after (update, insert, delete) ... ca sa nu fie blocaje. Daca reuseste sa faca update pe serverul urmator bine - daca nu logheaza si o sa faca cand o sa fie online (cu un job probabil). NU asteapta unii dupa altii ca atunci ajung la blocaje.</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5753.aspx</link><pubDate>Mon, 06 Oct 2008 14:53:57 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5753</guid><dc:creator>rremus</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5753.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5753</wfw:commentRss><description>Dar in felul asta introduci artificial puncte de failure. Daca in 'mesh' un nod e cazut, el numai primeste updaturile pina nu revine online. In cerc, daca un nod e cazut blocheaza pe toata lumea eventual (toate updaturile se opresc la el).&lt;br&gt;&lt;br&gt;Ca sa intzeleg mai bine, ceea ce propui tu este asa: S1 primeste un update. In trigger el se conecteaza la un linked server S2, promoveaza tranzactia locala in DTC, apoi updateaza remote S2. Batch-ul din S1 este blocat asteptind rezultatul de la linked server. S2 face update, apoi ruleaza trigger-ul sau. In trigger se conecteaza la linked server S3, adauga si pe S3 la DTC-ul care-l are cu S1 face update-ul pe S3. Batchul de pe S1 este acum blocat asteptind batch-ul de pe S2 care este acuma blocat asteptind batch-ul de pe S3. Si asa mai departe. Sn in trigger-ul detecteaza ca update-ul vine de la S1 si numai apeleaza S1 . Asta pentru, dupa cum sper ca stii, daca Sn se conecteaza la S1 va incerca sa enroleze o noua sesiune in tranzactia existenta, rezultind in eroarea 3910 "Transaction context in use by another session".&lt;br&gt;Deci toate serverele, de la S1 la Sn sin acuma enrolate intr-o tranzactie distribuita coordonata de MSDTC de pe S1 (care a inceput-o). Fiecare server este blocat asteptind-ul pe urmatorul sa termine batch-ul. Sn ruleaza trigger-ul de update (fara sa se conecteze la S1, am explicat de ce), apoi Sn-1 poate continua si tot asa pina controlul se intoarce la S1. Acuma S1 poate termina trigger-ul, statement-ul care a facut update-ul in sfirsit poate sa se termine, si eventula tranzactia sa comita. S1 cere DTC-ului sa&amp;nbsp; comita, DTC-ul face magia in doi pasi si toate serverele comit.&lt;br&gt;&lt;br&gt;&lt;br&gt;</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5752.aspx</link><pubDate>Mon, 06 Oct 2008 13:44:11 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5752</guid><dc:creator>fgbogdan</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5752.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5752</wfw:commentRss><description>pai ... decat sa se sincronizeze fiecare cu fiecare, asa o sa fie o directie de sincronizare. Ceea ce ziceam si la inceputul postului. Din punct de vedere al numarului de operatii e acelasi lucru in online dar in offline se complica treaba.</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5747.aspx</link><pubDate>Mon, 06 Oct 2008 12:13:06 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5747</guid><dc:creator>rremus</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5747.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5747</wfw:commentRss><description>Nu cred ca am inteles care sint avantajele sa pui serverele in inel. Potzi sa le explici?&lt;br&gt;</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5738.aspx</link><pubDate>Mon, 06 Oct 2008 10:46:28 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5738</guid><dc:creator>fgbogdan</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5738.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5738</wfw:commentRss><description>5-95 ... mda ... in momentul in care se mareste numarul de servere raportul se va modifica prin mecanismul pe care il propun.&lt;br /&gt;&lt;br /&gt;Stiu ca este complicat (altfel ... fara suparare) era un simplu addon la sql server si nu ne mai bateam niciunul capul.&lt;br /&gt;Sunt convins ca nu o sa pot sa ajung la o solutie in care sa pot pune oricate servere ... dar daca ajung sa fac o implementare cu 3 in inel ... m-am scos.&lt;br /&gt;&lt;br /&gt;Cand o sa mai am timp de "experimentari" o sa definitivez si partea de offline si o sa va prezint solutia completa.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;conditia aia de while ... mi-a furat-o clipboardul ... care nu vrea sa scrie (mai mic)(egal)(coada de maimuta)LastColumnID</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5736.aspx</link><pubDate>Mon, 06 Oct 2008 09:42:28 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5736</guid><dc:creator>rremus</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5736.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5736</wfw:commentRss><description>Cum tzi-a placut matematica in scoala?&lt;br&gt;&lt;BLOCKQUOTE&gt;&lt;div&gt;&lt;img src="http://sqlserver.ro/Themes/default/images/icon-quote.gif"&gt; &lt;strong&gt;fgbogdan:&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&amp;nbsp;5% write - 95% read&lt;br&gt;adica sa se replice tot - nu numai anumite tabele sau parti din ele.&lt;br&gt;&lt;/div&gt;&lt;/BLOCKQUOTE&gt;&lt;br&gt;Problema cu replicatul tot este urmatoarea: read-urile sint locale, dar write-urile sint globale. Adica un write trebuie replicat intre toate nodurile.&lt;br&gt;Hai sa zicem ca ai 5 noduri. Sa luam 1000 de operatii, 50 sint write si 950 sint read. Indiferent care este tehnologia folosita, in conditii ideale (nici un retry)&amp;nbsp; ca sa replici cel 50 de write-uri trebuie sa adaugi 50 de read-uri (cit citesti write-urile ca sa le shipezi la celelate noduri) si 200 de write-uri (cele 50 de write-uri de la cele 4 noduri partenere). Deci deodata ai 1000 de readuri si 250 de writeuri, ceea ce inseamna 80% read si 20% write. In plus, tu suportzi 1250 de operatii din care doar 1000 sint locale. Hai sa zicem ca firma are un success nebun (cel mai periculos lucru care se poate intimpla aplicatiei tale!) si deschide 20 de filiale/depozite sau ce sint nodurile tale. Acuma cele 1000 de tranzactii locale sau transformat, dupa aceasi formula, in 2000 de tranzacti, 50% read 50% write si doar 50% si doar 50% din capacitatea locala serveste cererile locale, restul este folosit doar sa shipeze si sa primeasca replici. Si 20 de noduri nu sint deloc o cifra serioasa, daca iei pur si simplu judetele din Romania ajungi repede la cifre mai mari. &lt;br&gt;&lt;br&gt;
Si ia in considerare ca acestea sint cele mai optimiste calcule. In realitate nici odata nu o sa ai success 100% si vor exista retry-uri, care vor altera si mai rau aceste calcule. In plus o aplicatzie optimizata pentru 95% read evident ca va avea o schema si indexsi pentru 95% read, si va avea problem serioase cind de fapt se fac 50% read-50% write.&lt;br&gt;&lt;br&gt;Facind aceste calcule simple potzi usor demonstra ca cerintele originale sint exagerate. Ma indoiesc ca este chiar nevoie sa se replice &lt;i&gt;tot la totzi&lt;/i&gt;.&lt;br&gt;&lt;br&gt;&lt;BLOCKQUOTE&gt;&lt;div&gt;&lt;img src="http://sqlserver.ro/Themes/default/images/icon-quote.gif"&gt; &lt;strong&gt;fgbogdan:&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;actualizare in timp real (stocuri si alte prostii)&lt;br&gt;sa se poata folosi aplicatia in mare masura a timpului&lt;br&gt;&lt;/div&gt;&lt;/BLOCKQUOTE&gt;&lt;br&gt;Orice design sincron trebuie sa ia in considerare ca practic daca un nod e picat intreaga aplicatie e picata. Hai sa zicem ca organizatia ta poate sa mentina un up-time de 98% (incluzind toate opririle pentru aplicare de patch-uri, toate problemele de hardware, si mai ales toate erorile de administrare/operare). Si sa consideram ca ISP-urile folosite au un uptime de 99.9% (putem cu totzii sa ne oprim din ris acuma). 5 noduri vor avea un uptime de (.98*.999)^^5 care inseamna 90% (ne putem juca cu formula, unii pot zice ca este (.98*.999)^^(5-1), altzii ca este .98^^5*.999, dar tot pe la aceleasi cifre ajungi). Adica 10% din timp aplicatia nu merge. 10 noduri e 80% uptime, iar 20 de noduri inseamna doar 65% uptime. Acuma sint convins ca orice beneficiar caruia ii prezintzi un timp de functionare de 65% &lt;i&gt;in conditzii ideale&lt;/i&gt; are toate motivele sa te dea afara pe usa.&lt;br&gt;&lt;br&gt;Deci din start potzi exclude orice solutzie sincrona care cere ca celelate noduri sa fie online pentru a putea face un write local.&lt;br&gt;In momentul care treci de la sincron la asincron, cam tot ce stii despre operatzii in baza de date sau despre CRUD devine obsolete. Trebuie sa gindesti intermeni de cozi, mesaje, latenta, update conflict si asa mai departe.&lt;br&gt;&lt;br&gt;Astea ar fi citeva idei de start ca sa-tzi dai seama de fapt ce ai in fatza. Sa obtzii ce vrei tu este &lt;i&gt;extrem&lt;/i&gt; de complicat, chiar si dupa ce ai relaxat bine de tot din cerintele care le-ai pus.&lt;br&gt;</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5722.aspx</link><pubDate>Sun, 05 Oct 2008 08:58:44 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5722</guid><dc:creator>ggciubuc</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5722.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5722</wfw:commentRss><description>&lt;P&gt;O alta metoda de sincronizare neamintita aici este data de tehnologia service broker din SQL:&lt;/P&gt;
&lt;P&gt;1.Cu ea poti face sincronizare prin mesaje asincrone;spuneti ca trebuie replicate toate informatiile, insa in mod real tabelele nomenclatoare se misca mai rar si&amp;nbsp;mai mult datele care se modifica in tranzactii, deci ar fi sanse sa nu fie traficul foarte mare si sa duca la gatuiri;&lt;/P&gt;
&lt;P&gt;2.Daca folosirea service broker ca mijloc de replicare este greoaie o puteti macar folosi in triggerii de care vorbiti aici: sa spunem ca un trigger este fired de 1000 de ori (adica de 1000 de ori sa zicem ca se face un insert pe tabela care lanseaza un trigger&amp;nbsp;), punand mesajele de raspuns ale triggerului intr-o coada service broker acestea vor curge asincron catre serverele target neblocand aplicatia care gazduieste triggerul de fata.&lt;/P&gt;
&lt;P&gt;3.Un motiv in plus sa apelati la aceasta tehnologie (ca vad ca sunteti la etapa de arhitectura si inca nu e decis nimic) este acela ca service broker vine gratuit la SQL Server Express 2005 care este la randul lui gratuit insa are limitarile stiute&lt;/P&gt;
&lt;P&gt;Iata o discutie de a mea cu unul dintre taticii tehnologiei, &lt;A href="http://sqlserver.ro/forums/post/1142.aspx"&gt;Remus Rusanu&lt;/A&gt;&amp;nbsp;despre service broker.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5721.aspx</link><pubDate>Sun, 05 Oct 2008 07:26:01 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5721</guid><dc:creator>rsocol</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5721.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5721</wfw:commentRss><description>Dezactivarea trigger-ului din cealalta baza de date poate cauza probleme daca se adauga simultan doua inregistrari (diferite) in doua server-e. E posibil ca inregistrarea adaugata in al doilea server sa nu mai declanseze trigger-ul (fiind dezactivat) si astfel sa nu se mai copieze pe celelalte server-e. In mod normal, in loc de dezactivarea trigger-ului, as scrie ceva cod in trigger (folosind TRIGGER_NESTLEVEL, CONTEXT_INFO() sau @@SPID) sa faca RETURN daca e apelat dintr-un alt trigger de acest gen. Din pacate, daca e vorba de alt server, cred ca aceste solutii nu prea sunt aplicabile si as face RETURN-ul in functie de HOST_NAME() si/sau SUSER_SNAME() (eventual, facand un login dedicat doar pentru linked server-urile folosite pentru "replicare").&lt;br&gt;&lt;br&gt;O alta problema ar fi ca datele din coloanele identity ar trebui copiate (folosind SET IDENTITY_INSERT ON), nu trebuie generat un nou ID, deoarece ar fi probabil diferit, iar la stergere te bazezi pe faptul ca are aceeasi valoare. Pe de alta parte, poti sa afli daca tabela are o coloana identity (folosind functia OBJECTPROPERTY cu parametrul 'TableHasIdentity') si poti sa afli care este coloana identity (folosind functia COLUMNPROPERTY cu parametrul 'IsIdentity').&lt;br&gt;&lt;br&gt;In afara de limitarile pe care le-ai mentionat, ar mai fi si faptul ca valoarea din coloana primary key nu trebuie sa se modifice niciodata. E adevarat ca in 99% din cazuri, oricum nu se poate modifica, pentru ca e identity (si chiar si daca n-ar fi, probabil exista foreign key-uri care nu au cascade update). Dar asa, ca idee, ar fi interesant sa analizezi ce ar face trigger-ul daca ID-ul nu este identity si ai 3 inregistrari in tabela BANCI (cu ID-urile 1, 2 si 3) si faci un "UPDATE BANCI SET ID=ID+1, DENUMIRE=DENUMIRE+DENUMIRE".&lt;br&gt;&lt;br&gt;O ultima observatie ar fi la linia "WHILE @ColumnID", care probabil ar trebui sa fie "WHILE @ColumnID&amp;lt;=@LastColumnID". Este interesant de stiut ca valorile din colid pot sa nu fie consecutive (daca a fost stearsa o coloana din tabela), dar cred ca e OK codul din acest punct de vedere.&lt;br&gt;&lt;br&gt;Razvan&lt;br&gt;</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5710.aspx</link><pubDate>Fri, 03 Oct 2008 10:49:37 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5710</guid><dc:creator>fgbogdan</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5710.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5710</wfw:commentRss><description>ok ... am pentru varianta online solutia cu triggere ... din pacate nu pot sa fac upload la fisiere (poate puneti o vorba buna la admin).&lt;br /&gt;Restrictiile "pe moment" sunt:&lt;br /&gt;- definitie de tabela sa fie mai mica de 8000 (suma dimensiuni campuri)&lt;br /&gt;-daca tabela are key ... sa fie pe prima coloana&lt;br /&gt;- coloanele autoincrement sa se stie (ca sa le elimin din lista de replicare)&lt;br /&gt;- nu se folosesc campuri text, ntext image&lt;br /&gt;&lt;br /&gt;Am realizat un "template" de trigger pe care apoi l-am "aplicat" pe toate tabelele din bazele de pe 2 servere cu ajutorul unei aplicatii care citeste structura tabelelor si seteaza variabilele din template.&lt;br /&gt;&lt;br /&gt;Pun un exemplu pentru o tabela banci.&lt;br /&gt;&lt;br /&gt;CREATE TRIGGER [REPLBANCI] ON [dbo].[BANCI]&lt;br /&gt;FOR INSERT, UPDATE, DELETE&lt;br /&gt;AS&lt;br /&gt;&lt;br /&gt;DECLARE @strAction AS VARCHAR(10)&lt;br /&gt;DECLARE @STRTABLENAME AS VARCHAR (100)&lt;br /&gt;DECLARE @STRCMD AS NVARCHAR (1000), @STRCMD1 AS NVARCHAR (1000)&lt;br /&gt;DECLARE @Column_Name  AS VARCHAR (50), @Type_Name AS VARCHAR (50)&lt;br /&gt;DECLARE @DeletedRows AS INT&lt;br /&gt;DECLARE @InsertedRows AS INT&lt;br /&gt;DECLARE @nIndex AS INT&lt;br /&gt;&lt;br /&gt;SELECT * INTO #inserted FROM inserted&lt;br /&gt;SET @InsertedRows = @@rowcount&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SELECT * INTO #deleted FROM deleted&lt;br /&gt;SET @DeletedRows = @@rowcount&lt;br /&gt;&lt;br /&gt;IF @InsertedRows &gt; 0&lt;br /&gt;BEGIN&lt;br /&gt;IF @DeletedRows &gt; 0&lt;br /&gt;	SET @strAction = 'UPDATE'&lt;br /&gt;ELSE&lt;br /&gt;	SET @strAction = 'INSERT'&lt;br /&gt;END&lt;br /&gt;ELSE&lt;br /&gt;BEGIN&lt;br /&gt;	SET @strAction = 'DELETE'&lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;-- DELETE&lt;br /&gt;IF 'DELETE' = @strAction&lt;br /&gt;BEGIN&lt;br /&gt;	SET @STRCMD = ' delete from [SRVDB2\SQL4].bcMainM2008.dbo.BANCI where BANCAID in (select BANCAID from #deleted)'&lt;br /&gt;	-- disable trigger&lt;br /&gt;	SET @strCMD1 = 'ALTER TABLE BANCI DISABLE TRIGGER REPLBANCI'&lt;br /&gt;	EXECUTE [SRVDB2\SQL4].bcMainM2008.DBO.SP_EXECUTESQL @strCMD1&lt;br /&gt;	--&lt;br /&gt;	EXECUTE(@STRCMD)&lt;br /&gt;	-- enable trigger&lt;br /&gt;	SET @strCMD1 = 'ALTER TABLE BANCI ENABLE TRIGGER REPLBANCI'&lt;br /&gt;	EXECUTE [SRVDB2\SQL4].bcMainM2008.DBO.SP_EXECUTESQL @strCMD1 &lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;-- INSERT&lt;br /&gt;IF 'INSERT' = @strAction&lt;br /&gt;BEGIN&lt;br /&gt;	SET @STRCMD = ' INSERT INTO [SRVDB2\SQL4].bcMainM2008.dbo.BANCI select BANCAID,NUME,CODBANCA,CODSWIFT,LOCALITID,LOCALIT,JUDETID,TARAID,TIPBANCA,ISANULAT,ISTEMPORAR,NTIPEXPORT,ADRESA from #inserted	'&lt;br /&gt;	-- disable trigger&lt;br /&gt;	SET @strCMD1 = 'ALTER TABLE BANCI DISABLE TRIGGER REPLBANCI'&lt;br /&gt;	EXECUTE [SRVDB2\SQL4].bcMainM2008.DBO.SP_EXECUTESQL @strCMD1&lt;br /&gt;	--&lt;br /&gt;	EXECUTE(@STRCMD)&lt;br /&gt;	-- enable trigger&lt;br /&gt;	SET @strCMD1 = 'ALTER TABLE BANCI ENABLE TRIGGER REPLBANCI'&lt;br /&gt;	EXECUTE [SRVDB2\SQL4].bcMainM2008.DBO.SP_EXECUTESQL @strCMD1 &lt;br /&gt;END&lt;br /&gt;&lt;br /&gt;-- UPDATE&lt;br /&gt;IF 'UPDATE' = @strAction&lt;br /&gt;BEGIN&lt;br /&gt;&lt;br /&gt;	DECLARE @ColumnID int, @Columns nvarchar(4000), @ObjectID int, @LastColumnID int&lt;br /&gt;	&lt;br /&gt;	SET @ObjectID=(SELECT id FROM sysobjects WHERE name='BANCI')&lt;br /&gt;	SET @LastColumnID=(SELECT MAX(colid) FROM syscolumns WHERE id=@ObjectID)&lt;br /&gt;	SET @ColumnID=1&lt;br /&gt;	WHILE @ColumnID&lt;br /&gt;		IF (SUBSTRING(COLUMNS_UPDATED(),(@ColumnID - 1) / 8 + 1, 1)) &amp;amp;&lt;br /&gt;		POWER(2, (@ColumnID - 1) % 8) = POWER(2, (@ColumnID - 1) % 8)&lt;br /&gt;		SET @Columns = ISNULL(@Columns+',','') + COL_NAME(@ObjectID,@ColumnID) + ' = #inserted.' + COL_NAME(@ObjectID,@ColumnID) + ' '&lt;br /&gt;		SET @ColumnID=@ColumnID+1&lt;br /&gt;	END&lt;br /&gt;&lt;br /&gt;	-- disable trigger&lt;br /&gt;	SET @strCMD1 = 'ALTER TABLE BANCI DISABLE TRIGGER REPLBANCI'&lt;br /&gt;	EXECUTE [SRVDB2\SQL4].bcMainM2008.DBO.SP_EXECUTESQL @strCMD1&lt;br /&gt;&lt;br /&gt;	-- trebuie sa inlocuiesc IN tabela tinta ... coloana @Column_Name&lt;br /&gt;	SET @STRCMD = 'UPDATE [SRVDB2\SQL4].bcMainM2008.dbo.BANCI SET ' + @Columns + ' FROM [SRVDB2\SQL4].bcMainM2008.dbo.BANCI C, #inserted WHERE C.BANCAID = #inserted.BANCAID'&lt;br /&gt;	EXECUTE(@STRCMD)&lt;br /&gt;&lt;br /&gt;	-- enable trigger&lt;br /&gt;	SET @strCMD1 = 'ALTER TABLE BANCI ENABLE TRIGGER REPLBANCI'&lt;br /&gt;	EXECUTE [SRVDB2\SQL4].bcMainM2008.DBO.SP_EXECUTESQL @strCMD1 &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;END&lt;br /&gt;DROP TABLE #inserted&lt;br /&gt;DROP TABLE #DELETED&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</description></item><item><title>Re: Solutia optima pentru aplicatie distribuita.</title><link>http://sqlserver.ro/forums/thread/5678.aspx</link><pubDate>Mon, 29 Sep 2008 07:09:52 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:5678</guid><dc:creator>ignatandrei</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/5678.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=16&amp;PostID=5678</wfw:commentRss><description>&lt;BLOCKQUOTE&gt;&lt;div&gt;&lt;img src="http://sqlserver.ro/Themes/default/images/icon-quote.gif"&gt; &lt;strong&gt;fgbogdan:&lt;/strong&gt;&lt;/div&gt;&lt;div&gt;

Eu o sa incerc si o sa va dau rezultatele cand reusesc.&lt;/div&gt;&lt;/BLOCKQUOTE&gt;&lt;br&gt;Tine-ne la curent...chiar sunt curios...&lt;br&gt;</description></item></channel></rss>