2014-08-27 56 views
1

有一種情況可以在不同的地方創建表。 所以,我有〜10個工作應用程序,可以同時嘗試創建一個相同的表。 問題。我如何同步它們?所以我沒有任何例外或錯誤?並發表創建

當一天結束時,應用程序的所有實例都試圖創建一個新表,所以當有類似00:00:00的時候,他們都會嘗試創建它。

對不起,對於可能的「愚蠢的問題」,一直在谷歌搜索一段時間,沒有結果。 謝謝。

+1

爲什麼不確定不會發生。也許根據應用程序試圖創建表的方式,在表名前面附加一些獨特的東西。即app1MyTable,app2MyTable,app3MyTable等。 – Linger 2014-08-27 12:54:49

+0

您會看到,它們全部10個都是一個應用程序的實例,並且它們都在該表中寫入日誌,所以在一個地方查看來自所有服務器的所有日誌將很高興 – Eramir 2014-08-27 12:56:54

+0

或在創建表之前先進行檢查以確保它不存在... – Darren 2014-08-27 12:57:07

回答

2

您可以使用sp_getapplock進行任意鎖定。在創建表之前,您可以讓您的應用程序使用此鎖。像這樣:

exec sp_getapplock 
if tabledoesnotexist 
create table ... 
-1

您可以請通過以下代碼...併發執行使用ISOLATION LEVEL SERIALIZABLE處理。

 CREATE PROCEDURE [dbo].[GetNextID](
      @IDName nvarchar(255) 
     ) 
     AS 
     BEGIN 
      /* 
       Description: Increments and returns the LastID value from tblIDs 
       for a given IDName 
       Author:   Max Vernon 
       Date:   2012-07-19 
      */ 

      DECLARE @Retry int; 
      DECLARE @EN int, @ES int, @ET int; 
      SET @Retry = 5; 
      DECLARE @NewID int; 
      SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; 
      SET NOCOUNT ON; 
      WHILE @Retry > 0 
      BEGIN 
       BEGIN TRY 
        BEGIN TRANSACTION; 
        SET @NewID = COALESCE((SELECT LastID FROM tblIDs WHERE IDName = @IDName),0)+1; 
        IF (SELECT COUNT(IDName) FROM tblIDs WHERE IDName = @IDName) = 0 
         INSERT INTO tblIDs (IDName, LastID) VALUES (@IDName, @NewID) 
        ELSE 
         UPDATE tblIDs SET LastID = @NewID WHERE IDName = @IDName; 
        COMMIT TRANSACTION; 
        SET @Retry = -2; /* no need to retry since the operation completed */ 
       END TRY 
       BEGIN CATCH 
        IF (ERROR_NUMBER() = 1205) /* DEADLOCK */ 
         SET @Retry = @Retry - 1; 
        ELSE 
         BEGIN 
         SET @Retry = -1; 
         SET @EN = ERROR_NUMBER(); 
         SET @ES = ERROR_SEVERITY(); 
         SET @ET = ERROR_STATE() 
         RAISERROR (@EN,@ES,@ET); 
         END 
        ROLLBACK TRANSACTION; 
       END CATCH 
      END 
      IF @Retry = 0 /* must have deadlock'd 5 times. */ 
      BEGIN 
       SET @EN = 1205; 
       SET @ES = 13; 
       SET @ET = 1 
       RAISERROR (@EN,@ES,@ET); 
      END 
      ELSE 
       SELECT @NewID AS NewID; 
     END 
     GO 
0

正如評論中提到的那樣,您的第一步是執行存在檢查。然後,如果有兩個同時創作的機會,您可以使用TRY...CATCH

IF Object_ID('test', 'U') IS NULL 
    BEGIN 
    BEGIN TRY 
     CREATE TABLE test (a int) 
    END TRY 
     BEGIN CATCH 
     SELECT Error_Message() 
     END CATCH 
    END 

UPDATE

每天都想創建一個表。認真。這是非常差的數據庫設計。

相反,您希望將datetime列添加到您的表中,以指示每條記錄何時創建。