2016-03-02 67 views
0

如果多线程并发查询以下SQL的数据库(PostgreSQL的):是数据库操作原子

UPDATE mytable SET n=n+1 WHERE n=0; 

不管是不是“N”终于将大于1

+0

假设你正在使用的交易,然后按[Postgres的(http://www.postgresql.org/about/)*完全符合ACID *,其中** ** ACID是*原子* * *一致,*隔离*和*耐用*。 –

+0

如果不使用事务,这个操作是否原子? – tomnotcat

+0

这里有很多操作。读取和写入是不同的步骤,这不是原子的。在这种情况下,它是* *安全,因为更新需要在该行的锁,直到它写入新的版本,然后退出持有它。 –

回答

1

更新将写锁,所以没有并发操作将实际发生在表上。

n will not be greater than 1. 
+0

不Postgres的使用行版本没有任何锁?我可能是错的,我只是好奇。 –

+0

@VladimirBaranov现在用*锁能够* [MVCC](http://www.postgresql.org/docs/current/static/mvcc.html)。 –

0

update mytable set n=n+1 where n=0;

不管是不是 'N' 终于将大于1

没有也不会是 “大于1” 因为添加10产量1

所以n等于1,而不是 “大于1”。

是的,它是保证所有先前为0(零)的值都是1(一)在更新完成后没有错误。

+0

这里棘手的部分是“以前”。在此更新正在运行时插入'n = 0'的行怎么办?如果另一个并发更新将n设置为0(n = 1)会怎么样?我认为了解事务隔离级别非常重要。最有可能的是,n不会大于1,但最终会出现一些仍然有n = 0的行。 –

+0

@VladimirBaranov:一(DML)语句看到数据库的一致状态,而语句运行 - 数据库是目前在该语句开始的状态。 –