数据库事务如果调用一个在 BEGIN TRANSACTION 和 COMMIT/ROLLBACK TRANSACTION 语句中封装了所需操作的存储过程,您就可以在到数据库服务器的单个往返行程中运行事务,从而实现最佳性能。数据库事务还支持嵌套事务,这意味着您可以从一个活动事务中启动一个新事务。 在下面的代码片断中,BEGIN TRANSACTION 语句开始了一个新事务。可以通过使用 COMMIT TRANSACTION 语句将更改提交到数据库来结束事务,或者,在发生任何错误的情况下,通过使用 ROLLBACK TRANSACTION 语句将所有更改撤消来结束事务: CREATE PROCEDURE Proc1 ???… AS -- Begin the transaction BEGIN TRANSACTION -- Do transaction operations ???… -- Check for any Error If @@Error <> 0 -- Rollback the Transaction ROLLBACK TRANSACTION ???… -- Commit the Transaction COMMIT TRANSACTION 下面的存储过程接受作为输入参数的定单的 XML 表示形式。为了在 Orders 和 OrderDetails 表中进行适当的插入,该存储过程使用 sp_xmlpreparedocument 系统存储过程来加载和分析 XML。正如您在代码中所看到的,存储过程在一个显式事务中封装了所有操作,因此,如果其中的任何操作执行失败,将回滚所做的所有更改。 注意,该过程将 XACT_ABORT 设置为 ON,此设置的作用是,如果其中的任何语句无法完成,SQL 服务器将自动回滚事务。 CREATE PROCEDURE InsertOrder @Order NVARCHAR(4000) = NULL , @OrderId int Output AS SET NOCOUNT ON DECLARE @hDoc INT DECLARE @PKId INT -- Specify that the SQL Server automatically rolls back the current -- transaction if a Transact-SQL statement raises a run-time error. SET XACT_ABORT ON -- Begin the transaction BEGIN TRANSACTION -- Load and Parse the incoming XML represeting an Order into an -- XMLDocument EXEC sp_xml_preparedocument @hDoc OUTPUT, @Order -- Select order header from the Order node in the XMLDocument and -- insert it into the Orders table INSERT Orders(CustomerId, OrderDate, ShipToName, ShipToAddressId, OrderStatus) SELECT CustomerId, CONVERT(DateTime,OrderDate), ShipToName, ShipToAddressId, OrderStatus FROM OPENXML(@hDoc, '/NewDataSet/Orders') WITH ( CustomerId int 'CustomerId', OrderDate nvarchar(23) 'OrderDate', ShipToName nvarchar(40) 'ShipToName', ShipToAddressId int 'ShipToAddressId', OrderStatus int 'OrderStatus') -- Select the OrderId of the Order just inserted into the Orders table -- to use it while inserting order details SELECT @PKId = @@IDENTITY -- Select order details from the Details node in the XMLDocument and -- insert them into the OrderDetails table INSERT OrderDetails (OrderId, ItemId, UnitPrice, Quantity) SELECT @PKId as OrderId, ItemId, UnitPrice, Quantity FROM OPENXML(@hDoc, '/NewDataSet/Details') WITH (ItemId int 'ItemId', UnitPrice money 'UnitPrice', Quantity int 'Quantity') -- Set the Output parameter Select @OrderId = @PKId -- Commit the transaction COMMIT TRANSACTION EXEC sp_xml_removedocument @hDoc RETURN 0 GO 虽然这种做法提供了良好的性能,但是,您仍然需要用 Transact SQL 编写代码,这可不象用诸如兼容 .NET 的语言编写代码那么简单 |
|