15

I am dubbing some SP at work and I have discover that whoever wrote the code used a transaction on a single update statement like this

begin transaction 
*single update statment:* update table whatever with whatever
commit transaction

I understand that this is wrong because transaction is used when you want to update multiple updates. I want to understand from the theoretical point, what are the implications of using the code as above? Is there any difference in updating the whatever table with and without the transaction? Are there any extra locks or something?

4

3 回答 3

8

可能由于先前或将来可能涉及其他数据的代码而包含该交易。也许那个开发人员只是养成了在事务中包装代码的习惯,以保证“安全”?

但是,如果该语句实际上只涉及对单行的一次更新,那么在这种情况下存在该代码确实没有任何好处。事务不一定会“锁定”任何东西,尽管其中执行的操作当然可以。它只是确保其中包含的所有操作要么全部执行,要么全部执行。

请注意,事务不是关于多个表,而是关于多个更新。它确保多次更新完全或不发生。

因此,如果您两次更新同一张表,则无论有没有事务都会有所不同。但是您的示例仅显示了一条更新语句,大概只更新了一条记录。

事实上,事务将多个更新封装到同一个表中可能很常见。想象一下:

INSERT INTO Transactions (AccountNum, Amount) VALUES (1, 200)
INSERT INTO Transactions (AccountNum, Amount) values (2, -200)

这应该包含在交易中,以确保正确转移资金。如果一个失败,另一个也必须失败。

于 2012-09-11T12:29:05.313 回答
7

我知道这是错误的,因为当您要更新多个表时使用事务。

不必要。这仅涉及一个表 - 仅 2 行:

--- transaction  begin

BEGIN TRANSACTION ;

UPDATE tableX 
SET Balance = Balance + 100
WHERE id = 42 ;

UPDATE tableX 
SET Balance = Balance - 100
WHERE id = 73 ;

COMMIT TRANSACTION ;

--- transaction  end
于 2012-09-11T12:28:27.350 回答
6

希望你同事的代码看起来更像这样,否则 SQL 会发出语法错误。根据 Ypercube 的评论,在事务中放置一个语句没有真正的目的,但这可能是一个编码标准或类似的。

begin transaction  -- Increases @@TRANCOUNT to 1
update table whatever with whatever
commit transaction  -- DECREMENTS @@TRANCOUNT to 0

通常,当直接针对 SQL 发出临时语句时,最好将语句包装在事务中,以防万一出现问题并且需要回滚,即

begin transaction -- Just in case my query goofs up
update table whatever with whatever
select ... from table ... -- check that the correct updates / deletes / inserts happened
-- commit transaction  -- Only commit if the above check succeeds.
于 2012-09-11T12:29:08.783 回答