我们有这个会计解决方案生态系统,基本上,它有两张表:
dbo.AccountFluxRecord
(
Id,
TotalCredits,
TotalDebits,
CreditMinusDebit,
Application (the application used to insert the record)
)
dbo.AccountFluxRecordDetail
(
Id,
AccountFluxId, (FK to above table)
Type, (Credit or Debit)
Value,
CreditBankAccountId, (nullable FK)
DebtBankAccountId (nullable FK)
)
我们有一些应用程序使用它,并且都使用存储过程来插入新记录。
SP_InsertAccountFluxRecord
我们将列表操作系统详细信息作为自定义用户表类型传递给 SP。它进行了大量验证,以确保所有记录至少有一个贷方和一个借方,并且贷方减去债务的总和为零。它还验证 BankAccountId 是否对每种操作都有效。
几年来,它在数百名客户中完美运行,每周插入数百万条记录。我们为大多数客户托管数据库,但其中一些坚持他们的数据必须在内部托管。我们可以接受,因为我们可以获得一个开放的维护渠道。
今天,我们遇到了其中一位客户自托管数据库的问题。
我们发现了十几个“坏”记录。这些记录缺少债务详细信息,这是不可能的,因为该特定应用程序从一对借记/贷记详细信息创建了一个 AccountFluxRecord,其中一个是另一个的镜像。如果没有一对有效的银行账户,它甚至无法接受用户输入,但我们发现在这些不良记录中 DebtBankAccountId 字段为空。
我们保留所有操作的日志,日志反映了错误记录按原样插入,没有删除或更新。Obs:我们确实使用快照事务模式来避免我们过去遇到的一些死锁问题。
TLDR 我得到了十几个无效记录,它们是由一个 SP 插入的,用于阻止插入无效记录,就好像所有应用程序和存储过程验证都被绕过了一样。下面有一个片段显示了如何在 SP 中处理验证。
IF (@SumDetailDebit <> @SumDetailCredit)
BEGIN
set @Mesage = @ErrorPrefix + N'TOTAL DEBIT IS DIFFERENT FROM CREDIT!';
THROW 50000, @Mesage ,1
END
问题:在进行一些验证后,在 SP 内有一个游标为每次迭代插入详细记录。即使我们没有在循环内使用事务控制,是否可以提交一个插入而回滚另一个插入?