我有一个方案,我要在MYSQL中执行update-insert(我要使用REPEATABLE-READ隔离级别) 方案是 -
there is a table -
+----+--------+--------+--------+
| ID | NAME | AMOUNT | STATUS |
+----+--------+--------+--------+
| 1 | NAME1 | 700 | ACTIVE |
+----+--------+--------+--------+
现在NAME = NAME1的每个新条目都应该用STATUS = INACTIVE更新旧条目,然后插入新条目,即
+----+--------+--------+----------+
| ID | NAME | AMOUNT | STATUS |
+----+--------+--------+----------+
| 1 | NAME1 | 700 | INACTIVE |
+----+--------+--------+----------+
| 2 | NAME1 | 800 | ACTIVE |
+----+--------+--------+----------+
如果两个事务要插入新条目(一个AMOUNT = 800,第二个AMOUNT = 900),则应将旧条目标记为INACTIVE,然后插入新条目。所以表(第一个实例)的最终输出应该是
+----+--------+--------+----------+
| ID | NAME | AMOUNT | STATUS |
+----+--------+--------+----------+
| 1 | NAME1 | 700 | INACTIVE |
+----+--------+--------+----------+
| 2 | NAME1 | 800 | INACTIVE |
+----+--------+--------+----------+
| 3 | NAME1 | 900 | ACTIVE |
+----+--------+--------+----------+
显然,会有竞争条件,但没有问题,结果表应该只有一个ACTIVE记录为NAME = NAME1
现在问题是 - 两个转换都通过更新已插入的行来插入其记录。所以最后我得到两条ACTIVE记录。即
+----+--------+--------+----------+
| ID | NAME | AMOUNT | STATUS |
+----+--------+--------+----------+
| 1 | NAME1 | 700 | INACTIVE |
+----+--------+--------+----------+
| 2 | NAME1 | 800 | ACTIVE |
+----+--------+--------+----------+
| 3 | NAME1 | 900 | ACTIVE |
+----+--------+--------+----------+
+--------------------------+-------------------------------+
| T1 | T2 |
+--------------------------+-------------------------------+
| START | START |
| update entry(ID=1) | wait for lock on entry(ID=1) |
| insert new entry(ID=2) | |
| commit | |
| | update entry(ID=1) |
| | insert new entry(ID=3) |
| | commit |
+--------------------------+-------------------------------+
我正在使用(并且必须使用)REPEATABLE READ,因此在这种情况下T2应该获得新的插入行(通过T1)(我认为这是幻读的情况)但是它没有发生。
关于如何最好地实现这一目标的任何建议也会有所帮助。
由于
答案 0 :(得分:0)
使用隔离级别SERIALIZABLE
,您不必担心。不,你不必须使用REPEATABLE READ
。您还可以设置每个会话的隔离级别。没有其他理由不这样做。