Transaction A:

```
ken2=# begin;
BEGIN
ken2=# select * from foo;
 id |  key   | value 
----+--------+-------
 23 | foobar | 
 21 | foo2   | b
(2 rows)

ken2=# delete from foo where key = 'foo2';       # runs just before the update on transaction B
DELETE 1
ken2=# commit;
COMMIT
ken2=# 
```

Transaction B:

```
ken2=# begin;
BEGIN
ken2=# select * from foo;
 id |  key   | value 
----+--------+-------
 23 | foobar | 
 21 | foo2   | b
(2 rows)

ken2=# delete from foo where key = 'foo2';
DELETE 1
ken2=# commit;
COMMIT
ken2=# select * from foo;
 id |  key   | value 
----+--------+-------
 23 | foobar | 
(1 row)
```

Transaction B started after transaction A, but its changes were not reflected, the data was ripped from underneath it.

With 'for update':

Transaction A:

```
ken2=# begin;
BEGIN
ken2=# select * from foo for update;
 id |  key   | value 
----+--------+-------
 23 | foobar | 
(1 row)

ken2=# delete from foo where key = 'foobar';
DELETE 1
ken2=# commit;
COMMIT
ken2=# 
```

Transaction B:

```
ken2=# begin
ken2-# ;
BEGIN
ken2=# select * from foo for update;       # this actually blocks until the other transaction commits
 id | key | value 
----+-----+-------
(0 rows)

ken2=# insert into foo (key, value) values ('foobar', 'newvalue');  # foobar doesn't exist, so it inserts, not updates!
INSERT 0 1
ken2=# commit;
COMMIT
ken2=# 
ken2=# select * from foo;
 id |  key   |  value   
----+--------+----------
 24 | foobar | newvalue
(1 row)
```

Transaction B, which came in later but blocked waiting for Transaction A starts, gets the right view of the world and does the correct thing with an insert this time.