1

SQLServer2005データベースがあります。Table AID列と、Id複数の行にまたがる別の手動列があります。2番目のid列はの形式で'0000000098'あり、文字列である必要があります。データ型を変更できません。

Function A最大ID列値を取得し、それを1つインクリメントして、文字列としてキャストします。

ストアドプロシージャは新しいIDを取得し、このIDを使用していくつかの挿入を実行します。

更新が発生する前に、2つのクライアントがストアドプロシージャを実行して同じIDを取得しないようにするにはどうすればよいですか?procが処理を完了するまで、読み取りからテーブルaをロックできますか、それともより効率的な方法がありますか?

データ型や構造を変更できれば簡単ですが、できません。

4

2 に答える 2

1

関数を単一のUPDATEステートメントとして定式化できる場合、明示的なロックは必要ありません。UPDATEステートメントには更新ロック ( U) が必要であり、これは排他的です。たとえば、2 つのリーダーが同じ行で同時に更新ロックを取得することはできません。

UPDATE dbo.TableA
SET ManualID = CAST(CAST(ManualID AS INT) + 1 AS VARCHAR(20))
OUTPUT Inserted.ManualID  -- return the newly inserted manual ID for your use
WHERE ..........

2 段階のプロセスが必要な場合は (SELECT前に)、次のヒントをUPDATE使用します。WITH (UPDLOCK)SELECT

DECLARE @OldManualID VARCHAR(20)

BEGIN TRANSACTION

SELECT @OldManualID = ManualID 
FROM dbo.TableA WITH (UPDLOCK)
WHERE........

-- do something with that manual ID

UPDATE dbo.TableA
SET ManualID = (new value of ManualID)
WHERE ..........

COMMIT TRANSACTION

どちらの場合も、単一の UPDATE または SELECT/UDPATE が更新ロックの下で実行されるため、2 つのプロセスがこれを同時に実行することはできません。それ以上のロックはまったく必要ないと思います-絶対に完全なテーブルロックではありません....

于 2011-12-21T06:02:01.143 に答える
0

はい、テーブルをロックできます。トランザクション内ですべてのことを行う必要があり、初めてテーブルを読み取るときに、ヒント (updlock、holdlock) または (TABLOCKX) を使用して排他的連続ロックを配置できます。

于 2011-12-21T03:31:01.537 に答える