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}"
}
問題を回避するか、少なくともそれをキャッチすることは素晴らしいことです。