Row was updated or deleted by an
测评公司对系统进行测评,发现某些页面并发两个就报错了loadrunner的26612错误,也就是说页面有报错,但单独访问并未发生过报错。
从服务器上拉下来日志看了一下,大量的报错:
Caused by: org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException: Object of class [com.lhcis.credit.ins.Company] with identifier [96736]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.lhcis.credit.ins.Company#96736]
经查,这个报错说明操作的对象时应用了乐观锁机制,或定义pojo时定义了version字段,而grails生成的数据库都是带有version的,仔细查代码,有以下问题:
//取notice信息
def notice = Notice.get(params.noticeId)
notice.hits = notice.hits + 1
def bodytext = notice.bodytext
//其余代码
notice.hits = notice.hits + 1
因为语法的原因,这个地方已经进行了保存,而后面又大量使用notice,这样,并发的时候,或者狂按F5的时候,version会更改导致后台大量报错。
修改如下:
def notice1 = Notice.get(params.noticeId)
notice1.hits = notice1.hits + 1
def notice = Notice.read(params.noticeId)
def bodytext = notice.bodytext
//其余代码
因为有一个点击量的计算,所以前面不得不使用get,但后面如果需要再次使用notice,可以使用read从数据库中read出来,然后再使用,就避免version变更因为后台报错。