2013-06-03 59 views
4

使用乐观锁定策略时,它可以解决像下面并发问题:乐观锁定绝对安全吗?

 
| the first transaction started  | 
|          | 
| select a row       | 
|          | the second transaction started 
| update the row with version checking | 
|          | select the same row 
| commit txn       | 
|          | update the row with version checking 
|          | 
|          | rolls back because version is dirty 

但是,如果在极少数情况下,如果在第二个事务更新是在第一笔交易,但之前的UDPATE后交易提交?

 
| the first transaction started  | 
|          | the second transaction started 
| select a row       | 
|          | select the same row 
| update the row with version checking | 
|          | update the row with version checking 
| commit txn       | 
|          | rolls back because version is dirty // will it? 
|          | 
|          | 

我做了一个实验,在第二个事务更新无法读取“脏”的版本,因为第一个事务还没有被提交。第二笔交易在这种情况下会失败吗?

+0

@亚当阿罗德谢谢你告诉我这句格言。我谷歌因为我不是一个本地的英语演讲者:)但乐观锁定策略会在我提到的情况下工作吗? – Hippoom

+0

如果真的乐观,你怎么使用交易功能?更新将自动失败,无需任何回滚。 – tia

+0

@tia也许在这个例子中,无论有无事务都可以。但有时我需要将其他更改(例如可能插入某个子表的某些子元素)回滚到数据库 – Hippoom

回答

2

你没有在你的问题中说你实际使用的数据库系统,所以我不知道你系统的细节。

但是在任何情况下,在乐观锁定系统下,进程不能只在执行更新语句时检查行版本,因为您确实担心您担心的问题。

对于完全可序列化的隔离事务,每个进程必须在提交时自动检查所检查和修改的所有行的行版本。因此,在第二种情况下,右侧流程在尝试提交之前不会检测到冲突(您未包含在右侧流程中的步骤)。当它尝试提交时,它会检测到冲突并回滚。

+0

感谢您的回复。我们在生产环境中使用Oracle 10g,隔离级别被读取提交。 – Hippoom

+0

它会在尝试提交时真的失败。我的意思是,当数字检查在使用乐观锁定时失败时,它不会抛出异常,它只是更新0行,而当受影响的行等于0时,开发人员会抛出异常。 – Hippoom

+0

也许我可以做另一个实验,在更新sql被执行,但在提交事务之前更新另一个线程中的同一行,然后唤醒第一个线程。 – Hippoom