从 grails 1.3 开始,我已经有一段时间记录“上次登录”的代码。现在在 grails 2.2.4 和“乐观锁定失败”让我很烦。我认为只有在我重新启动应用程序时才会发生这种情况。我想知道如何更好地解决它并避免“乐观锁定错误”。涉及到 spring-security 和 spring-security-ui。
class InteractiveAuthenticationSuccessEventListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
private static final Logger LOG = Logger.getLogger('au.com.interlated.emissionscalculator.InteractiveAuthenticationSuccessEventListener')
void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
ResPerson person
try {
ResPerson.withTransaction {
person = ResPerson.findById(event.authentication.principal.id)
if (!person.isDirty()) {
if (!person.isAttached())
person.attach()
person.lastLoggedIn = new Date()
// doesn't save it is not the end of the world. Wondering if multiple requests at a time can cause this.
try {
person.merge(flush: true)
然后我抓住了我能想到的一切——包括交易和“person.merge”。如果不进行此更新,这不是一个大问题。事实上,它可能是因为过滤器被其他东西调用了。
ERROR emissionscalculator.InteractiveAuthenticationSuccessEventListener
- Object of class [au.com.interlated.springSecurity.ResPerson] with identifier [3100]: optimistic locking failed;
nested exception is org.hibernate.StaleObjectStateException:
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [au.com.interlated.springSecurity.ResPerson#3100]
我试过捕捉一堆异常:
} catch (e) {
LOG.error "Failed to save login record : ${e.message}"
} catch (OptimisticLockingFailureException olfe) {
LOG.error "Failed to save login record. Optimistic Locking Failure."
} catch (org.hibernate.StaleObjectStateException sose) {
LOG.error "Failed to save login record (stale object) ${sose.message}"
}
要么避免这个问题,要么至少抓住它会很棒。