假设我有以下域类:
class Book {
String name
// more properties here, but name is the only one relevant for this example
}
我想通过视图更新它的名称。我正在使用以下表格来更新它:
<g:form action="updateName" id="${book.id}">
<g:hiddenField name="version"/>
<g:textField name="name"/>
...
</g:form>
在控制器中,我使用以下逻辑:
def updateName() {
println("IN UPDATENAME()")
def book = Book.get(params.id)
println("VERSION BEFORE ASSIGN: ${book.version})
book.version = params.long('version')
println("VERSION AFTER ASSIGN: ${book.version})
book.name = params.name
book.save(flush: true)
...
}
我通过在 2 个不同的浏览器中打开相同的编辑页面来测试它。我updateName
在一个浏览器中做,然后是另一个。第二个updateName
应该是抛出一个OptimisticLockingFailureException
,但事实并非如此。
我启用了 SQL 输出,这就是我在日志中得到的:
IN UPDATENAME()
VERSION BEFORE ASSIGN: 0
VERSION AFTER ASSIGN: 0
update book set version=?, name=? where id=? and version=?
binding parameter [1] as [BIGINT] - 1
binding parameter [2] as [STRING] - 'abc123'
binding parameter [3] as [BIGINT] - 1
binding parameter [4] as [BIGINT] - 0
IN UPDATENAME()
VERSION BEFORE ASSIGN: 1
VERSION AFTER ASSIGN: 0
update book set version=?, name=? where id=? and version=?
binding parameter [1] as [BIGINT] - 1
binding parameter [2] as [STRING] - 'def456'
binding parameter [3] as [BIGINT] - 1
binding parameter [4] as [BIGINT] - 1
换句话说,在第二次调用中,我能够成功地将版本从 1 分配到 0,这应该导致异常,但由于某种原因,SQL 调用仍然错误地检查版本 = 1 而不是 0。有人知道为什么会这样吗?