我只想了解“更新丢失”的含义,这是通过交易解决的。
请看下面两个事务,我使用mysql 5.5.8和innodb存储引擎:
create table counter (what varchar(5), id integer, count integer, primary key (id));
insert into counter values ('total', 0, 0);
session 1 (T1) session 2(T2)
-------------------------------------------------------------------------
0 | begin;
-------------------------------------------------------------------------
1 begin; |
-------------------------------------------------------------------------
2 select count from counter |
where id = 0; |
-------------------------------------------------------------------------
3 | update counter set count = 50
| where id = 0;
-------------------------------------------------------------------------
4 | commit;
------------------------------------------------------------------------
5 update counter set count |
= 1000 where id = 0; |
-------------------------------------------------------------------------
6 commit; |
-------------------------------------------------------------------------
您可以将值1000和50视为:
因此,这是典型的读写 - 写入依赖性。
在 session1(T1)之后提交并执行'从计数器中选择计数,其中id = 0',计数将为1000.我想知道它是否更新丢失或不?如果不是为什么?如果我记得正确,任何类型的更新都将在任何隔离级别中避免。
其中一个可能的解决方法是使用“从计数器中选择计数,其中id = 0表示更新;”在步骤2,这相当于在记录上添加xlock,因此T2将被阻止。所以这是串行执行的 [T1,T2] 。
这是Innodb的(已知)错误吗?注意,这不等于执行 [T2,T1] ,因为T1将使用此序列读取50其他0,并且最终结果将不同。
由于
答案 0 :(得分:2)
是的,当然更新丢失了。对于外部世界,您的交易仅在提交时才“真正”执行。对于第三方,您的架构对应于:
你实际上甚至不需要交易:交易没有区别。如果你的会话1选择AFTER会话2进行更新,它们就很重要。在这种情况下,对于事务,会话1将读取值0,但没有事务,它将读取值50。
答案 1 :(得分:0)
这是因为INNODB默认隔离级别REPEATABLE READ
答案 2 :(得分:0)
是的,您的情况正是丢失更新意味着什么。在postgresql中,T1将被dbms中止以防止更新丢失。