读事务遇到并发写会出现脏读(读-提交和可重复读可以解决),写事务并发会带来一些冲突,最值得关注的就是更新丢失问题。 应用程序从数据库读取某些值,然后应用逻辑做出修改,然后写回新值。

原子写操作

UPDATE counters SET value=value+1 WHERE key = 'foo';

原子操作通常采用方式:

  1. 对读取对象加独占加锁,这种技术有时被称为「游标稳定性」。
  2. 强制所有原子操作都在单线程上执行。

显式枷锁

BEGIN TRANSACTION;
SELECT * FROM figures
  WHERE name = 'robot' AND game_id = 222
  FOR UPDATE;  -- 指示数据库对返回的所有结果行要加锁。

缺点:侵入应用逻辑、容易引发死锁(竞争冲突)。

自动检测更新丢失

数据库(Oracle 的串形化和 SQL Server 的快照级别隔离)可以自动检测何时发生了更新丢失,然后终止违规的那个事务。

原子比较和设置

UPDATE wiki_pages SET content = 'new_content'
  WHERE id = 1234 AND conetnt = 'old_content';

冲突解决与复制