1

我在 Google App Engine 上的应用程序中遇到严重错误。

当我这样做时:

CompanyUser.validate("email", email);
    CompanyUser.validate("password", password, password);
    Validator.checkValidation();

    CompanyUser user;
    
    try {
        user = company.getUserByEmail(email);

        //(user.getPassword() == "") se o usuário administrador resetar a senha, alterar o e-mail ou cadastrar um novo usuário
        //(user.isWaitingConfirmation()) nos mesmos casos acima e mais quando o usuário alterar seu próprio e-mail ou o usuário administrador se cadastrar (cadastro na home do site)
        if(Tools.isEmptyString(user.getPassword()) || user.isWaitingConfirmation()) {
            if(user.getLastAccessDate() == null)    //Se for usuário novo
                throw new AuthenticationException("Seu usuário encontra-se bloqueado.<br />Para ativar seu acesso ao portal, acesse seu e-mail e siga as instruções.");
            else
                throw new AuthenticationException("Seu usuário encontra-se bloqueado.<br />Para reativar seu acesso ao portal, acesse seu e-mail e siga as instruções.");
        }

        byte[] bDigest = user.getPasswordBytes();
        byte[] bSalt = user.getPasswordSaltBytes();
        byte[] proposedDigest = user.getHash(password, bSalt);
        
        if (Arrays.equals(proposedDigest, bDigest)) {
            try{
                user.setLastAccessDate(Tools.getCurrentTime());
                company.saveDetached();
            } catch (DeadlineExceededException e) {
                Tools.sendMail("ERRO Severidade média: Não esta salvando ultimo acesso de Usuario", "ERRO: Não esta salvando ultimo acesso do Usuario " + user.getEmail() + " da empresa " + user.getCompany().getName()+ "" +
                        "Objeto esta com transação aberta.", Tools.getChaintSupportEmail());
            }
            return user;
        }

    } catch (ObjectNotFoundException e) {
        user = null;
    }
    
    throw new AuthenticationException("Usuário/Senha não conferem");

public Object saveDetached() throws InvalidFieldsValueException {
    
    if(IdModel.getErrorList().isEmpty() == false) {
        Vector<ValidatorError> el = IdModel.getErrorList();
        Validator.clearError();
        throw new InvalidFieldsValueException(el);
    }

    return  PersistenceManager.saveDetached(this, true);
    
}

public static Object saveDetached(Object object, boolean detach) {
    Object ob = null;
    String msg ="";
    javax.jdo.PersistenceManager pm = getPM();
    pm.setDetachAllOnCommit(detach);
    
    Transaction t = pm.currentTransaction();
    try {
        t.begin();
        ob = pm.makePersistent(object);
        t.commit();
    } catch (Exception e) {
        String[] fieldNames = NucleusJDOHelper.getDetachedObjectDirtyFields(object, pm);
        for(String s:fieldNames) {
            msg = msg.concat(s+";\n");
        }
        
    } finally {
        String[] fieldNames;
        if (t.isActive()) {
            fieldNames = NucleusJDOHelper.getDetachedObjectLoadedFields(object, pm);
            msg = msg+"NucleusJDOHelper.getDetachedObjectLoadedFields";
            for (String s : fieldNames) {
                msg = msg.concat(s + ";\n");
            }
            Tools.getLogger().warning(msg);
            t.rollback();
        }
        pm.close();
    }
    return ob;
}

有时候是这样的:

201.86.195.206 - - [24/Sep/2012:14:24:48 -0700] "GET / HTTP/1.1" 500 0 - "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1" "tci.chainit.com.br" ms=60020 cpu_ms=22858 exit_code=104 instance=00c61b117c6e51b4aec6d2e4089516b479c2a0 E2012-09-24 18:24:47.974 org.datancle.资源回滚失败:org.datanucleus.store.appengine.DatastoreXAResource@2d659,错误代码 UNKNOWN 和事务:[DataNucleus Transaction,ID=Xid= W2012-09-24 18:24:48.375 / com.google.apphosting 错误。 runtime.HardDeadlineExceededError:此请求 (b08d8999601781ee) 于 2012/09/24 21:23:48.426 UTC 开始,并且仍在 2012/09/24 21:24:48.373 UTC 执行。在 java.util.concurrent.locks 的 sun.misc.Unsafe.park(Native Method)。在 com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:336) 在 com.google.tracing 的 com.google.tracing.TraceContext.runInContext(TraceContext.java:701) 运行(TraceContext.java:459) .TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:328) 在 com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:456) 在 com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java :251) 在 java.lang.Thread.run(Thread.java:679) C2012-09-24 18:24:48.376 来自 servlet com.google.apphosting.runtime.HardDeadlineExceededError 的未捕获异常:此请求 (b08d8999601781ee) 于 2012 年开始/09/24 21:23:48.426 UTC 并且仍在 2012/09/24 21:24:48.373 UTC 执行。在 java.util.concurrent.locks.LockSupport 的 sun.misc.Unsafe.park(Native Method)。

处理此请求的进程遇到问题,导致它退出。这可能会导致一个新进程被用于对您的应用程序的下一个请求。如果您经常看到此消息,则可能是在应用程序初始化期间引发了异常。(错误代码 104)

对我来说,回滚操作似乎没有在每个请求必须结束的 60 秒内完成,并且回滚操作被取消。通过这种方式,对象以我们无法在其上书写的状态结束。

在我看来,这个问题非常严重,因为用户对象以这种“不可更改”状态结束,并且无法由它自己修复,也不能由我们的 Datanucleous 的 JDO 修复。

4

0 回答 0