私は数年間T-SQLを開発してきましたが、常に掘り下げて、言語のすべての側面についてできる限りのことを学び続けています。私は最近新しい会社で働き始め、取引に関して奇妙な提案だと思うものを受け取りました。それらを使用しないでください。代わりに、トランザクションをシミュレートする回避策を使用してください。これは、1つのデータベースで多くのトランザクションを処理し、その後多くのブロッキングを行うDBAによるものです。私が主に作業しているデータベースはこの問題の影響を受けず、トランザクションは過去に使用されたことがあります。
トランザクションはブロックすることが本来の性質であるため、トランザクションでブロックすることが期待されていることを理解しています。しかし、各ステートメントが正常に実行されなければならない場合が多くあります。1つが失敗した場合、それらはすべてコミットに失敗する必要があります。
私は常にトランザクションの範囲をできる限り狭く保ち、常にSET XACT_ABORT ONと組み合わせて使用し、常にTRY / CATCH内で使用しています。
例:
CREATE SCHEMA someschema;
GO
CREATE TABLE someschema.tableA
(id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
ColA VARCHAR(10) NOT NULL
);
GO
CREATE TABLE someschema.tableB
(id INT NOT NULL IDENTITY(1, 1) PRIMARY KEY,
ColB VARCHAR(10) NOT NULL
);
GO
CREATE PROCEDURE someschema.ProcedureName @ColA VARCHAR(10),
@ColB VARCHAR(10)
AS
SET NOCOUNT, XACT_ABORT ON;
BEGIN
BEGIN TRY
BEGIN TRANSACTION;
INSERT INTO someschema.tableA(ColA)
VALUES(@ColA);
INSERT INTO someschema.tableB(ColB)
VALUES(@ColB);
--Implement error
SELECT 1/0
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
IF @@trancount > 0
BEGIN
ROLLBACK TRANSACTION;
END;
THROW;
RETURN;
END CATCH;
END;
GO
ここに彼らが私がすることを提案したものがあります。
GO
CREATE PROCEDURE someschema.ProcedureNameNoTransaction @ColA VARCHAR(10),
@ColB VARCHAR(10)
AS
SET NOCOUNT ON;
BEGIN
BEGIN TRY
DECLARE @tableAid INT;
DECLARE @tableBid INT;
INSERT INTO someschema.tableA(ColA)
VALUES(@ColA);
SET @tableAid = SCOPE_IDENTITY();
INSERT INTO someschema.tableB(ColB)
VALUES(@ColB);
SET @tableBid = SCOPE_IDENTITY();
--Implement error
SELECT 1/0
END TRY
BEGIN CATCH
DELETE FROM someschema.tableA
WHERE id = @tableAid;
DELETE FROM someschema.tableB
WHERE id = @tableBid;
THROW;
RETURN;
END CATCH;
END;
GO
コミュニティへの私の質問は次のとおりです。これは、トランザクションの実行可能な回避策として意味がありますか?
私がトランザクションについて知っていること、およびソリューションが提案していることからの私の意見は、いいえ、これは実行可能なソリューションではなく、多くの障害点をもたらします。
推奨される回避策では、4つの暗黙的なトランザクションが発生しています。tryでの2つの挿入と、catchでの削除のためのさらに2つのトランザクション。挿入を「元に戻す」が、何もロールバックせず、実際には何もロールバックされない。
これは、彼らが提案している概念を示すための非常に基本的な例です。この例の複数の結果セットと2つのパラメーター値の「ロールバック」が想像できるように非常に複雑になるため、私がこれを行ってきた実際のストアドプロシージャのいくつかは、それらを徹底的に長く管理しにくくしています。「ロールバック」は現在手動で行われているため、本物だから何かを見逃す機会があります。
私が存在すると思う別の問題は、タイムアウトまたは切断された接続に関するものです。これはまだロールバックされますか?これは、これらの場合にトランザクションがロールバックされるように、SET XACT_ABORT ONを使用する理由についての私の理解です。
事前にフィードバックいただきありがとうございます!