无法将数据库状态与 Grails Hibernate 中的会话错误同步
Posted
技术标签:
【中文标题】无法将数据库状态与 Grails Hibernate 中的会话错误同步【英文标题】:Could not synchronize database state with session Error in Grails Hibernate 【发布时间】:2013-07-01 02:38:46 【问题描述】:我在我的 Grails 应用程序中注册了一个 MySecurityEventListener,用于在用户登录后设置登录次数。
MySecurityEventListener 类:
class MySecurityEventListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent>, LogoutHandler
/**
* Handler for after login.
*/
@Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event)
User.withNewSession
User user = User.get(event.authentication.principal.id)
user.lastLoginDate = new Date() // set the last login date
user.loginCount += 1 // increase the login count
user.isLoggedIn = true
user.save(flush: true)
/**
* Handler for after logout.
*/
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
User.withNewSession
User user = User.get(authentication.principal.id)
user.isLoggedIn = false
user.save(flush: true)
有时当用户登录时,我会收到以下错误:
| Error 2013-07-03 13:40:56,306 [http-nio-8080-exec-1]
ERROR events.PatchedDefaultFlushEventListener -
Could not synchronize database state with session Message:
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [demo.User#ffd93c5639b54405bf]
Line | Method
->> 38 | doCall in demo.MySecurityEventListener$_onApplicationEvent_closure1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 33 | onApplicationEvent in demo.MySecurityEventListener
| 1145 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
2013-07-03 13:40:56,551 [http-nio-8080-exec-1] INFO cpr.SessionSupport - Session created
2013-07-03 13:40:56,554 [http-nio-8080-exec-2] INFO cpr.SessionSupport - Session created
| Error 2013-07-03 13:40:56,554 [http-nio-8080-exec-1] ERROR [/demo].[gsp] - Servlet.service() for servlet [gsp] in context with path [/demo] threw exception
Message: Object of class [demo.User] with identifier [ffd93c5639b54405bf]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [demo.User#ffd93c5639b54405bf]
Line | Method
->> 38 | doCall in demo.MySecurityEventListener$_onApplicationEvent_closure1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 33 | onApplicationEvent in demo.MySecurityEventListener
| 1145 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
Caused by StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [demo.User#ffd93c5639b54405bf]
->> 38 | doCall in demo.MySecurityEventListener$_onApplicationEvent_closure1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 33 | onApplicationEvent in demo.MySecurityEventListener
| 1145 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
我该如何解决这个错误?
【问题讨论】:
使用withNewSession
而不是withTransaction
背后的基本原理是什么?
Npt 确定。你有什么推荐的?
withTransaction
或 withSession
使用 SessionFactory 提供的默认会话。你应该先试试。
我应该使用哪一个?如果你写一个答案我可以同意你!
希望答案有所帮助。
【参考方案1】:
withTransaction 提供对底层事务的访问。如果需要控制事务回滚,您可以使用它。
withSession 使用 SessionFactory 提供的默认会话。如果需要控制会话,请使用它。
看看你的例子,我保证withTransaction
(最简单的一个)。
【讨论】:
我可以同时使用这两个吗?每个 grails 操作都在其自己的会话中处理,我说得对吗? @confile 每个请求命中操作都有自己的休眠会话。你可以同时使用。以上是关于无法将数据库状态与 Grails Hibernate 中的会话错误同步的主要内容,如果未能解决你的问题,请参考以下文章
无法让 Elasticsearch 插件与 Grails 3 一起使用
grails 3(spring-boot) - 如何配置hibernate二级缓存