18 Mayıs 2011 Çarşamba

Microsoft Distributed Transaction Coordinator (MSDTC) Uzak bağlantısı ve daha fazlası. Remote Connection MSDTC and more

Bugün iki farklı bilgisayarda veri bütünlüğünü koruyabilmek için bir delete trigger'a ihtiyaç duydum. Sunucu A üzerine Sunucu B'yi Link server olarak ekledim. After Delete Triggerımı ilgili tabloya ekledim. Trigger içerisinde Sunucu B de yeralan bir tabloyu eden bir script bulunmaktaydı. Trigger'ın tetiklenmesini sağladığımda ise

MSDTC 'ın Sunucu B de çalışmadığını belirten
"MSDTC on server 'servername' is unavailable"
hatasını aldım.

Bunun sebebi trigger içerisine mevcut transactionın gönderilmesi ve trigger içerisinde uzak sunucuya ulaşmaya çalışmaktır.


Uzak sunucularda yeralan ortak iki transaction işlemi, özel bir servis olan MSDTC tarafından yönetilir.


Sunucu B ye gidip çalıştıra gidip "services.msc" yazdım ve açılan pencereden Distributed Transaction Coordinator 'ı bulup start ettim. Sunucu A da da servisin çalıştığından emin oldum.Tekrar denediğimde bu sefer farklı bir hata beni bekliyordu.



"The partner transaction manager has disabled its support for remote/network transactions."

Bu durumu çözmek için dcomcnfg.exe yazıp açılan pencerede sırasıyla

--Component Service
--Computers
--My Computer
--Distributed Transaction Coordinator
--Local DTC

Sağ click properties


Security tabında bulunan aşağıdaki alanları işaretledim.
Network DTC Access
Allow Remote Clients
Allow Remote Administration
Allow InBound
Allow OutBound
Enable XA Transactions

İki sunucuda da bu ayarları yaptım. Tekrar denediğimde hala network erişiminin olmadığını söyledi.

Bu arada bu testleri herseferinde trigger tetikleyerek değil daha kolay bir yol olan DTCping.exe ile yapabilirsiniz. DOWNLOAD

İki sunucuda da exeyi çalıştırın. Sunucuların Netbios isimlerini yazın. Sırasıyla A ve B sunucularında PING buttonuna tıklayın. Hata almıyorsanız işlem tamamdır.

Alınan hataları yorumlamak için

http://blogs.msdn.com/b/distributedservices/archive/2008/11/12/troubleshooting-msdtc-issues-with-the-dtcping-tool.aspx#AccessisDenied
adresini ziyaret edebilirsiniz.

Firewall ayarlarına MSDTC çalışabilmesi için gerekli 135 RPC endpoint portunu exception olarak ekledim.

Firewall ayarlarından emin olduktan sonra tekrar denedim tekrar aynı problemi yaşadım.


Eğer sizde de sunuculardan birisi Xp, Vista veya Win7 ise sizde bu problemi yaşayabilirsiniz.

Bunun için yapılması gereken;

1. Click Start, click Run, type Regedit, and then click OK.
2. Locate and then click the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT
3. On the Edit menu, point to New, and then click Key.
Note If the RPC registry key already exists, go to step 5.
4. Type RPC, and then press ENTER.
5. Click RPC.
6. On the Edit menu, point to New, and then click DWORD Value.
7. Type RestrictRemoteClients, and then press ENTER.
8. Click RestrictRemoteClients.
9. On the Edit menu, click Modify.
10. In the Value data box, type 0, and then click OK.
Note To enable the RestrictRemoteClients setting, type1.
11. Close Registry Editor and restart the computer.

Yukarıdaki işlemleri tamamlayıp tekrar denediğinizde başarıya ulaşacaksınız.


16 Mayıs 2011 Pazartesi

Büyük datalar ile Insert işlemi

Büyük datalar ile insert işlemi yaparken sunucu belleğini gereksiz yormanız çok olası.

The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions.

Bu tarz işlemler yaparken yukarıdaki gibi bir hata bile alabilirsiniz.

Büyük datalarla insert işlemi yaparken dikkat edilmesi gereken birkaç temel maddeyi sıralamak gerekirse;

--Hedef tablodaki gereksiz Indexleri kullanım dışına alınız. İşlem bittikten sonra rebuild ediniz.
--Mümkünse MSSQL 'in mevcut veri transferi protokollerini kullanınız.
--BULK INSERT tercih ediniz.
--Eğer normal insert yapıyorsanız ihtiyacınız yok ise "120 rows affected" gibi etkilenen kayıt sayacını kapatınız. (SET NOCOUNT ON)

try,catch,finally pattern in ADO.NET

try catch finally desenini ado.net işlemlerinde kullanırken dikkat etmenizi tavsiye edeceğim ufak bir nokta var. Kolayca gözden kaçabileceği için yazmak istedim.

SqlConnection con=null;
try
{
con = new SqlConnection();
SqlCommand cmd = new SqlCommand("",con);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
}
catch (Exception ex)
{

MessageBox.Show(ex.Message);
}
finally
{
if (con!=null && con.State != ConnectionState.Closed)
{
con.Close();
con.Dispose();
}
}

Gibi bir desen kullanıyorsanız catch bloğuna bir daha bakmanızı tavsiye ederim. MessageBox 'ın açacağı form modal olduğu için connection MessageBox ekranda olduğu sürece sonlanmayacaktır. Benzer deseni transaction işlemleri için kullandığınızı varsayarsak transaction askıda kalacaktır.

DROP AUTOGENERATED STATISTICS MSSQL

DECLARE @sm nvarchar(150)

DECLARE merge_cursor CURSOR FAST_FORWARD FOR SELECT (select o.name from sys.objects o where o.object_id=s.object_id)+'.'+name FROM sys.stats s WHERE s.auto_created=1

OPEN merge_cursor

FETCH NEXT FROM merge_cursor INTO @sm

WHILE @@FETCH_STATUS = 0
BEGIN

declare @q nvarchar(1000)
set @q='DROP STATISTICS '+@sm
execute sp_executesql @q

FETCH NEXT FROM merge_cursor INTO @sm
END

CLOSE merge_cursor
DEALLOCATE merge_cursor

Showing active open transaction in MSSQL

DBCC OPENTRAN

--OR

SELECT L.request_session_id AS SPID,
DB_NAME(L.resource_database_id) AS DatabaseName,
O.Name AS LockedObjectName,
P.object_id AS LockedObjectId,
L.resource_type AS LockedResource,
L.request_mode AS LockType,
ST.text AS SqlStatementText,
ES.login_name AS LoginName,
ES.host_name AS HostName,
TST.is_user_transaction as IsUserTransaction,
AT.name as TransactionName,
CN.auth_scheme as AuthenticationMethod
FROM sys.dm_tran_locks L
JOIN sys.partitions P ON P.hobt_id = L.resource_associated_entity_id
JOIN sys.objects O ON O.object_id = P.object_id
JOIN sys.dm_exec_sessions ES ON ES.session_id = L.request_session_id
JOIN sys.dm_tran_session_transactions TST ON ES.session_id = TST.session_id
JOIN sys.dm_tran_active_transactions AT ON TST.transaction_id = AT.transaction_id
JOIN sys.dm_exec_connections CN ON CN.session_id = ES.session_id
CROSS APPLY sys.dm_exec_sql_text(CN.most_recent_sql_handle) AS ST
WHERE resource_database_id = db_id()
ORDER BY L.request_session_id

REBUILD ALL INDEX FROM MSSQL DATABASE

DECLARE @Database VARCHAR(255)
DECLARE @Table VARCHAR(255)
DECLARE @cmd NVARCHAR(500)
DECLARE @fillfactor INT

SET @fillfactor = 50

DECLARE DatabaseCursor CURSOR FOR
SELECT name FROM master.dbo.sysdatabases
WHERE name IN ('energy')
ORDER BY 1

OPEN DatabaseCursor

FETCH NEXT FROM DatabaseCursor INTO @Database
WHILE @@FETCH_STATUS = 0
BEGIN

SET @cmd = 'DECLARE TableCursor CURSOR FOR SELECT table_catalog + ''.'' + table_schema + ''.'' +
table_name as tableName FROM ' + @Database + '.INFORMATION_SCHEMA.TABLES
WHERE table_type = ''BASE TABLE'''

-- create table cursor
EXEC (@cmd)
OPEN TableCursor

FETCH NEXT FROM TableCursor INTO @Table
WHILE @@FETCH_STATUS = 0
BEGIN

-- SQL 2000 command
--DBCC DBREINDEX(@Table,' ',@fillfactor)

-- SQL 2005 command
SET @cmd = 'ALTER INDEX ALL ON ' + @Table + ' REBUILD WITH (FILLFACTOR = ' +
CONVERT(VARCHAR(3),@fillfactor) + ')'
EXEC (@cmd)

FETCH NEXT FROM TableCursor INTO @Table
END

CLOSE TableCursor
DEALLOCATE TableCursor

FETCH NEXT FROM DatabaseCursor INTO @Database
END
CLOSE DatabaseCursor
DEALLOCATE DatabaseCursor

DISABLE / ENABLE MSSQL INDEX -TSQL

USE AdventureWorks
GO
----Diable Index
ALTER INDEX [IX_StoreContact_ContactTypeID] ON Sales.StoreContact DISABLE
GO
----Enable Index
ALTER INDEX [IX_StoreContact_ContactTypeID] ON Sales.StoreContact REBUILD
GO