我在工作中配音一些SP,我发现编写代码的人在单个更新语句中使用了这样的事务
begin transaction
*single update statment:* update table whatever with whatever
commit transaction
我知道这是错误的,因为当您想要更新多个更新时会使用事务。 我想从理论上理解,使用上述代码有什么含义? 在有和没有交易的情况下更新任何表有什么区别吗?有没有额外的锁或东西?
答案 0 :(得分:7)
由于可能涉及其他数据的先前或可能的未来代码,可能包含该交易。也许开发人员只是习惯于在交易中包装代码,以便“安全”?
但是如果语句只涉及单个行的单个更新,那么在这种情况下,那里的代码确实没有任何好处。交易不一定会锁定'当然,任何事情都可以在其中进行。它只是确保其中包含的所有操作都是全有或全无的。
请注意,交易不是关于多个表,而是关于多个更新。它确保多次更新全部或全部发生。
因此,如果您要更新同一个表两次,那么无论是否有交易都会有所不同。但是您的示例只显示了一个更新语句,可能只更新了一条记录。
事实上,事务可能会将多个更新封装到同一个表中。想象一下:
INSERT INTO Transactions (AccountNum, Amount) VALUES (1, 200)
INSERT INTO Transactions (AccountNum, Amount) values (2, -200)
这应该包含在交易中,以确保资金正确转移。如果一个失败了,另一个失败了。
答案 1 :(得分:6)
我知道这是错误的,因为当你想要更新多个表时会使用事务。
不一定。这只涉及一个表 - 只有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
答案 2 :(得分:4)
希望您的同事的代码看起来更像这样,否则SQL会发出语法错误。 根据Ypercube的评论,在一个事务中放置一个语句没有真正的目的,但可能这是一个编码标准或类似的。
begin transaction -- Increases @@TRANCOUNT to 1
update table whatever with whatever
commit transaction -- DECREMENTS @@TRANCOUNT to 0
通常,在直接针对SQL发布adhoc语句时,最好将语句包装在事务中,以防万一出现问题并且需要回滚,即
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.