当事务的所有要求都满足并且记录事务信息时,我的程序正确地注册了所有事务。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