如果其他语句依赖于第一个,是否有必要使用事务?
Is it necessary to use a transaction if other statements are dependent on the first?
长期以来,我一直忽略使用 SQL 交易,主要是出于无知。
但是假设我有这样的程序:
CREATE PROCEDURE CreatePerson
AS
BEGIN
declare @NewPerson INT
INSERT INTO PersonTable ( Columns... ) VALUES ( @Parameters... )
SET @NewPerson = SCOPE_IDENTITY()
INSERT INTO AnotherTable ( @PersonID, CreatedOn ) VALUES ( @NewPerson, getdate() )
END
GO
在上面的例子中,第二个插入依赖于第一个,因为如果第一个失败,它将失败。
其次,无论出于何种原因,就正确实施而言,交易让我感到困惑。我在这里看到一个例子,那里看到另一个例子,我刚刚打开 adventureworks 找到另一个带有 try、catch、rollback 等的例子。
我没有记录错误。我应该在这里使用交易吗?这值得么?
如果是,应该如何正确实施?根据我见过的例子:
CREATE PROCEURE CreatePerson
AS
BEGIN TRANSACTION
....
COMMIT TRANSACTION
GO
或者:
CREATE PROCEDURE CreatePerson
AS
BEGIN
BEGIN TRANSACTION
COMMIT TRANSACTION
END
GO
或者:
CREATE PROCEDURE CreatePerson
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION
END
END CATCH
END
最后,在我的真实代码中,我有更多类似 5 个独立的插入,全部基于新生成的人员 ID。如果你是我,你会怎么做?这个问题可能是多余的或重复的,但无论出于何种原因,我似乎无法在脑海中找到处理这个问题的最佳方法。
另一个令人困惑的地方是回滚。如果事务必须作为单个操作单元提交,如果不使用回滚会发生什么情况?或者仅在类似于 vb.net/c# 错误处理的 Try/Catch 中才需要回滚?
如果第一次插入成功而第二次插入失败,您的数据库将处于错误状态,因为 SQL 服务器无法读懂您的想法。它会将第一个插入(更改)留在数据库中,即使您可能希望它全部成功或全部失败。
为确保这一点,您应该按照上一个示例中的说明将所有语句包装在 begin transaction 中。重要的是要有一个捕获,以便明确回滚任何半完成的事务并尽快释放资源(由事务使用)。
您可能忽略了这一点:事务假设将一组单独的操作合并为一个,因此如果一个操作失败,您可以回滚并且您的数据库将保持原状,就好像什么也没发生一样。
比方说,如果您正在商店中保存购买的详细信息,这会更容易查看。您保存了客户的数据(如姓名或地址),但不知何故,您错过了详细信息(服务器崩溃)。所以现在你知道 John Doe 买了东西,但你不知道是什么。您 数据完整性 受到威胁。
如果您想在 SP 中处理交易,您的第三个示例代码是正确的。要return一个错误,你可以试试:
RETURN @@ERROR
回滚后。另外,请查看:
set xact_abort on
如:SQL Server - transactions roll back on error?
长期以来,我一直忽略使用 SQL 交易,主要是出于无知。
但是假设我有这样的程序:
CREATE PROCEDURE CreatePerson
AS
BEGIN
declare @NewPerson INT
INSERT INTO PersonTable ( Columns... ) VALUES ( @Parameters... )
SET @NewPerson = SCOPE_IDENTITY()
INSERT INTO AnotherTable ( @PersonID, CreatedOn ) VALUES ( @NewPerson, getdate() )
END
GO
在上面的例子中,第二个插入依赖于第一个,因为如果第一个失败,它将失败。
其次,无论出于何种原因,就正确实施而言,交易让我感到困惑。我在这里看到一个例子,那里看到另一个例子,我刚刚打开 adventureworks 找到另一个带有 try、catch、rollback 等的例子。
我没有记录错误。我应该在这里使用交易吗?这值得么?
如果是,应该如何正确实施?根据我见过的例子:
CREATE PROCEURE CreatePerson
AS
BEGIN TRANSACTION
....
COMMIT TRANSACTION
GO
或者:
CREATE PROCEDURE CreatePerson
AS
BEGIN
BEGIN TRANSACTION
COMMIT TRANSACTION
END
GO
或者:
CREATE PROCEDURE CreatePerson
AS
BEGIN
BEGIN TRY
BEGIN TRANSACTION
...
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRANSACTION
END
END CATCH
END
最后,在我的真实代码中,我有更多类似 5 个独立的插入,全部基于新生成的人员 ID。如果你是我,你会怎么做?这个问题可能是多余的或重复的,但无论出于何种原因,我似乎无法在脑海中找到处理这个问题的最佳方法。
另一个令人困惑的地方是回滚。如果事务必须作为单个操作单元提交,如果不使用回滚会发生什么情况?或者仅在类似于 vb.net/c# 错误处理的 Try/Catch 中才需要回滚?
如果第一次插入成功而第二次插入失败,您的数据库将处于错误状态,因为 SQL 服务器无法读懂您的想法。它会将第一个插入(更改)留在数据库中,即使您可能希望它全部成功或全部失败。
为确保这一点,您应该按照上一个示例中的说明将所有语句包装在 begin transaction 中。重要的是要有一个捕获,以便明确回滚任何半完成的事务并尽快释放资源(由事务使用)。
您可能忽略了这一点:事务假设将一组单独的操作合并为一个,因此如果一个操作失败,您可以回滚并且您的数据库将保持原状,就好像什么也没发生一样。
比方说,如果您正在商店中保存购买的详细信息,这会更容易查看。您保存了客户的数据(如姓名或地址),但不知何故,您错过了详细信息(服务器崩溃)。所以现在你知道 John Doe 买了东西,但你不知道是什么。您 数据完整性 受到威胁。
如果您想在 SP 中处理交易,您的第三个示例代码是正确的。要return一个错误,你可以试试:
RETURN @@ERROR
回滚后。另外,请查看:
set xact_abort on
如:SQL Server - transactions roll back on error?