我在 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 修复。