Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle db表锁定行和entityManager状态_Oracle_Hibernate_Seam_Entitymanager_Seam2 - Fatal编程技术网

Oracle db表锁定行和entityManager状态

Oracle db表锁定行和entityManager状态,oracle,hibernate,seam,entitymanager,seam2,Oracle,Hibernate,Seam,Entitymanager,Seam2,我有一个会话范围的类,它包含一个用于管理用户统计信息的对象。当用户登录(通过SSO)时,应用程序范围的方法会检查表中是否有活动会话-如果发现任何活动会话,则使用表中的会话id使会话无效 将一行添加到会话作用域类中的userStats表中: /** * get all the info needed for collecting user stats, add userStats to the users session and save to userStats table

我有一个会话范围的类,它包含一个用于管理用户统计信息的对象。当用户登录(通过SSO)时,应用程序范围的方法会检查表中是否有活动会话-如果发现任何活动会话,则使用表中的会话id使会话无效

将一行添加到会话作用域类中的userStats表中:

/**
     * get all the info needed for collecting user stats, add userStats to the users session and save to userStats table
     * this happens after session is created
     * @param request
     */
    private void createUserStats(HttpServletRequest request){
        if (!this.sessionExists) {
            this.userStats = new UserStats(this.user, request.getSession(true)
                    .getId(), System.getProperty("atcots_host_name"));
            request.getSession().setAttribute("userstats", this.userStats);
            Events.instance().raiseEvent("userBoundToSession", this.userStats);
            this.sessionExists = true;
            log.info("user " + this.user + " is now logged on");

            // add this to the db
            try {
                this.saveUserStatsToDb();
            } catch (Exception e) {
                log.error("could not save " + this.userStats.getId().getPeoplesoftId() + " information to db");
                e.printStackTrace();
            }           

        }

    }
当用户的会话被破坏时,该行将随着注销时间而更新

由于我无法解释或复制的原因,在过去两周内有2个用户登录并锁定了该行。当这种情况发生时,该用户的任何数据库调用都不再可能,并且该应用程序实际上对此用户不可用

 [org.hibernate.util.JDBCExceptionReporter] (http-127.0.0.1-8180-3) SQL Error: 0, SQLState: null
2012-07-26 18:45:53,427 ERROR [org.hibernate.util.JDBCExceptionReporter] (http-127.0.0.1-8180-3) Transaction is not active: tx=TransactionImple < ac, BasicAction: -75805e7d:3300:5011c807:6a status: ActionStatus.ABORT_ONLY >; - nested throwable: (javax.resource.ResourceException: Transaction is not active: tx=TransactionImple < ac, BasicAction: -75805e7d:3300:5011c807:6a status: ActionStatus.ABORT_ONLY >)
这根本不会进行db调用。 我已尝试手动回滚事务,但没有乐趣

当我在一个表中锁定一行,该行包含在对话作用域级别使用的数据时,结果几乎没有灾难性的结果——没有数据被保存,但它会恢复

预计到达时间:

我尝试提出一个AsynchronousEvent—它在本地工作,但部署到我们的远程测试服务器—这很奇怪—我得到:

    DEBUG [org.quartz.core.JobRunShell] (qtz_Worker-1) Calling execute on job DEFAULT.2d0badb3:139030aec6e:-7f34
    INFO  [com.mypkg.myapp.criteria.SessionCriteria] (qtz_Worker-1) observing predestroy for seam
    DEBUG [com.mypkg.myapp.criteria.SessionCriteria] (qtz_Worker-1) destroy destroy destroy sessionCriteria
    ERROR [org.jboss.seam.async.AsynchronousExceptionHandler] (qtz_Worker-1) Exeception thrown whilst executing asynchronous call
    java.lang.IllegalArgumentException: attempt to create create event with null entity
            at org.hibernate.event.PersistEvent.<init>(PersistEvent.java:45)
            at org.hibernate.event.PersistEvent.<init>(PersistEvent.java:38)
            at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:619)
            at org.hibernate.impl.SessionImpl.persist(SessionImpl.java:623)
...

如何从中恢复?

首先,在
组件中指定一个作用域。getInstance()
不会在指定的作用域中创建组件
EntityManager
实例始终位于对话上下文中(无论是临时的还是长期运行的)。
getInstance()
scope
参数的唯一目的是提示组件应该在其中的上下文,以避免在所有上下文中进行昂贵的搜索(如果不指定上下文或指定错误的上下文,就会发生这种情况)

由于前面的错误,事务被标记为回滚。如果entityManager无论如何都要提交,那么它将不是事务性的(事实上,事务保证在发生错误时不会保留任何内容)。如果要将登录事务与统计数据收集隔离开来,最简单的解决方案是在异步事件中执行
saveUserStatsToDb
方法(事务绑定到线程,因此使用不同的线程可以确保在单独的事务中处理事件)

大概是这样的:

@Observer("saveUserStatsEvent")
@Transactional
public void saveUserStatsToDb(UserStats stats) {
    ((EntityManager)Component.getInstance("entityManager")).persist(stats);
}
在您的
createUserStats
方法中:

Events.instance().raiseAsynchronousEvent("saveUserStatsEvent", this.userStats);

然而,这只是通过将交易一分为二来规避问题。你真正想解决的是问题根源的锁定条件。

Thanx关于回复,我更新了我原来的帖子。我确实解决了锁定条件,但我仍然需要找到一种方法来解决这个问题,我在收集涉及持久性的异常数据时也遇到了同样的问题。
@Observer("saveUserStatsEvent")
@Transactional
public void saveUserStatsToDb(UserStats stats) {
    ((EntityManager)Component.getInstance("entityManager")).persist(stats);
}
Events.instance().raiseAsynchronousEvent("saveUserStatsEvent", this.userStats);