Grails乐观锁定奇怪的行为

时间:2009-12-09 18:28:29

标签: hibernate grails gorm optimistic-locking

我一直在尝试让GORM在集成测试中抛出乐观的锁定错误。之前已经说过,如果不诉诸多个线程就不可能测试并发更新错误,但即便如此,我发现我的测试用例的行为令人惊讶:

void testOptimisticLocking() {

    new Widget(foo:"bar").save(flush:true)

    // Get the widget and change a property
    def widget = Widget.findByFoo("bar")
    assertNotNull widget
    widget.foo = "baz"
    def widgetVersion = widget.version
    println "widget: $widgetVersion"   // >>>  widget: 0

    // Discard the widget without saving; Hibernate now knows nothing about it
    widget.discard()

    // Get a different instance of the same widget from the database,
    // with the old value for foo
    def sameWidget = Widget.findByFoo("bar")
    assertNotNull sameWidget
    assertFalse System.identityHashCode(sameWidget) == System.identityHashCode(widget)

    // Change the foo property and save
    sameWidget.foo = "bat"
    sameWidget.save(flush:true)

    // Check the version has incremented
    println "sameWidget: $sameWidget.version"         // >>>  sameWidget: 1
    assertTrue widgetVersion < sameWidget.version

    // Check the database hold the "bat" widget
    sameWidget.discard()
    assertEquals 0, Widget.countByFoo("bar")
    assertEquals 1, Widget.countByFoo("bat")

    // Reattach the original widget and try to save it
    assertFalse widget.isAttached()
    widget.attach()
    println "widget: $widget.version"            // >>>  widget: 0
    assertEquals widgetVersion, widget.version
    assertEquals "baz", widget.foo

    // TEST FAILS HERE
    // No error is thrown, and the update fails silently!
    shouldFail(org.hibernate.StaleStateException) {
        assertTrue widget.validate()
        widget.save(flush:true)
        println widget.foo              // >>>  baz
        widget.discard()
        println "baz: " + Widget.countByFoo("baz")    // >>>  baz: 0
        println "bat: " + Widget.countByFoo("bat")    // >>>  bat: 1
    }



}

重新附加的Widget实例不会持久存储到数据库中,但不会抛出任何异常!

我的测试用例颇为人为,但我仍对结果感到惊讶。

有人可以解释一下吗?

0 个答案:

没有答案