當事務的所有要求都滿足並且記錄事務信息時,我的程序正確地註冊了所有事務。SQL事務在失敗時不記錄,但事務仍然通過
但是,當錯誤的信息給出的信息不記錄,但交易仍然通過,我不知道我做錯了什麼。
首先是存儲過程的日誌中的交易信息
/****** Object: StoredProcedure [dbo].[LogTransactionAttempt] Script Date: 8/1/2017 9:57:24 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[LogTransactionAttempt]
(@ToUserAccountId int,
@FromUserAccountId int,
@TransferAmount money,
@CreditorWithdrawl nvarchar(50),
@TransferCode numeric(18,0))
AS
BEGIN
INSERT INTO Transactions (FromUserAccountId, ToUserAccountId, TransferAmount,
CreditorWithdrawal, TransferCode, TransactionDateTime)
VALUES (@FromUserAccountId, @ToUserAccountId, @TransferAmount,
@CreditorWithdrawl, @TransferCode, GETDATE())
RETURN @@IDENTITY
END
這裏是整個過程
/****** Object: StoredProcedure [dbo].[performTransaction] Script Date: 8/1/2017 9:57:05 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[performTransaction]
(@ToUserAccountId int,
@FromUserAccountId int,
@TransferAmount money,
@CreditorWithdrawl nvarchar(50),
@TransferCode numeric(18,0))
AS
BEGIN
DECLARE @FromUserAccountTest INT
SELECT @FromUserAccountTest = (SELECT Count(*)
FROM dbo.UserAccount
WHERE UserAccountId = @FromUserAccountID)
IF @FromUserAccountTest <> 1
BEGIN
RAISERROR('From Account Does Not Exist', 10, 1)
END
DECLARE @ToUserAccountTest INT
SELECT @ToUserAccountTest = (SELECT Count(*)
FROM dbo.UserAccount
WHERE UserAccountId = @ToUserAccountID)
IF @ToUserAccountTest <> 1
BEGIN
RAISERROR('To Account Does Not Exist', 10, 2)
END
-- At this point we can log the transaction
DECLARE @TransactionID INT
EXEC @TransactionID = dbo.LogTransactionAttempt @ToUserAccountId, @FromUserAccountId, @TransferAmount, @CreditorWithdrawl, @TransferCode
-- Check to see if sufficient balance
DECLARE @FromAccountBalance MONEY
SELECT @FromAccountBalance = (SELECT CreditBalance
FROM dbo.UserAccount
WHERE UserAccountID = @FromUserAccountID)
IF (@FromAccountBalance < @TransferAmount)
BEGIN
RAISERROR('Insufficient Balance', 10, 3)
END
-- Now we can start the transaction
BEGIN TRANSACTION
UPDATE UserAccount
SET CreditBalance = CreditBalance - @TransferAmount
WHERE UserAccountId = @FromUserAccountID
IF (@@ERROR <> 0)
BEGIN
ROLLBACK TRANSACTION /* if errors - rollback transaction */
RETURN
END
UPDATE UserAccount
SET CreditBalance = CreditBalance + @TransferAmount
WHERE UserAccountID = @ToUserAccountID
IF (@@ERROR <> 0)
BEGIN
ROLLBACK TRANSACTION /*if errors - rollback transaction */
RETURN
END
UPDATE dbo.Transactions
SET Successful = 1
WHERE TransactionID = @TransactionID
IF (@@ERROR <> 0)
BEGIN
ROLLBACK TRANSACTION /* if errors - rollback transaction */
RETURN
END
-- Transaction
COMMIT TRANSACTION
END -- Procedure
就像我說的一切都運行完美,當輸入是正確的,但如果有一個不好的輸入說不存在帳戶或資金不足,它不記錄失敗,但交易仍然通過
編輯 嘗試從10切換到16沒有影響
例子的正確的事務移動從帳戶11 $ 100爲$ 100的平衡以說明22無平衡
USE [Transaction]
GO
DECLARE @return_value int
EXEC @return_value = [dbo].[performTransaction]
@ToUserAccountId = 22,
@FromUserAccountId = 11,
@TransferAmount = 100,
@CreditorWithdrawl = N'credit',
@TransferCode = 1
SELECT 'Return Value' = @return_value
GO
該正確的條目返回
1017 22 11 100.0000 credit 1 2017-08-02 10:19:23.110 yes
在交易日誌中
輸入錯誤信息,例如從一個賬戶轉賬150美元,餘額只有100美元ES錯誤代碼正常,但不會取消,即使所請求的錢是不是都在那裏
USE [Transaction]
GO
DECLARE @return_value int
EXEC @return_value = [dbo].[performTransaction]
@ToUserAccountId = 22,
@FromUserAccountId = 11,
@TransferAmount = 150,
@CreditorWithdrawl = N'credit',
@TransferCode = 2
SELECT 'Return Value' = @return_value
GO
事務返回
(1 row(s) affected)
Msg 50000, Level 16, State 3, Procedure performTransaction, Line 72 [Batch Start Line 2]
Insufficient Balance
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
(1 row(s) affected)
所以有錯誤顯示的消息的下面,但錯誤的交易沒有登錄,但交易仍通過導致負平衡
USE [Transaction]
GO
/****** Object: StoredProcedure [dbo].[LogTransactionAttempt] Script Date: 8/2/2017 9:20:54 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[LogTransactionAttempt]
(
@ToUserAccountId int,
@FromUserAccountId int,
@TransferAmount money,
@TransferCode numeric(18,0)
)
AS
BEGIN
INSERT INTO Transactions
(
UserAccountId,
TransferAmount,
CreditorWithdrawal,
TransferCode,
TransactionDateTime
)
VALUES
(
@FromUserAccountId,
@TransferAmount,
'Withdrawl',
@TransferCode,
GETDATE()
)
,
(
@ToUserAccountId,
@TransferAmount,
'Credit',
@TransferCode,
GETDATE()
)
RETURN @@IDENTITY
END
錯誤級別爲10的Raiserror可能太低而無法正確捕獲。我試着把它撞到16.比如說,如果你沒有使用try/catch塊,你可能還需要設置xact_abort。這應該至少可以防止隨後的事務繼續並在您遇到raiserror時進行承諾 – Xedni