Playframework 2.0 播放两次新框架帖子,生成两个相同的对象

Playframework 2.0 播放两次新框架帖子,生成两个相同的对象,playframework-2.0,save,data-synchronization,bad-request,Playframework 2.0,Save,Data Synchronization,Bad Request,我的注册表在使用Play 2时出现问题。 注册表是存储患者数据的疾病注册表。每个患者都与一个诊断类别有一对一的关系。 一切都很好。但偶尔我发现在我们的数据库中已经创建了两次诊断。当我查看访问日志时,我发现了以下内容 //访问患者(2)页面 194.176.xxx.xxx---[03/Oct/2014:00:09:16+1000]“GET/npd/npc/patient/2http/1.1”200 11470 //访问患者(2)的诊断更新页面,诊断不存在,重定向到诊断创建 194.176.xxx.

我的注册表在使用Play 2时出现问题。 注册表是存储患者数据的疾病注册表。每个患者都与一个诊断类别有一对一的关系。 一切都很好。但偶尔我发现在我们的数据库中已经创建了两次诊断。当我查看访问日志时,我发现了以下内容

//访问患者(2)页面

194.176.xxx.xxx---[03/Oct/2014:00:09:16+1000]“GET/npd/npc/patient/2http/1.1”200 11470

//访问患者(2)的诊断更新页面,诊断不存在,重定向到诊断创建

194.176.xxx.xxx---[03/Oct/2014:00:09:44+1000]“GET/npd/npc/diagnostics/2/update HTTP/1.1”303-

//访问患者的诊断创建页面(2)

194.176.xxx.xxx---[03/Oct/2014:00:09:45+1000]“GET/npd/npc/Diagnostics/new/2 HTTP/1.1”200 69806

//尝试保存诊断,收到错误请求

194.176.xxx.xxx---[03/Oct/2014:00:12:56+1000]“POST/npd/npc/diagnostics/new/2 HTTP/1.1”400 55909

194.176.xxx.xxx---[03/Oct/2014:00:12:56+1000]“POST/npd/npc/diagnostics/new/2 HTTP/1.1”400 70198

//成功存储诊断,重定向到查看页面

194.176.xxx.xxx---[03/Oct/2014:00:13:11+1000]“POST/npd/npc/diagnostics/new/2 HTTP/1.1”303-

194.176.xxx.xxx---[03/Oct/2014:00:13:11+1000]“POST/npd/npc/diagnostics/new/2 HTTP/1.1”303-

//访问诊断视图页面

194.176.xxx.xxx---[03/Oct/2014:00:13:13+1000]“GET/npd/npc/Diagnostics/2 HTTP/1.1”200 11925

出于某种原因,save Diagnostics收到了两次错误的请求(我认为这是客户端的问题,可能是他们的浏览器被黑客攻击了或其他什么)。但我的控制器有一个检查,看看是否存在诊断。下面是我的保存方法

public static Result save(long patientId) {
    Patient patient = Ebean.find(Patient.class, patientId);

    if (patient == null) {
        flash("error", "Patient does not exist.");
        return PatientController.home();
    }

    if (patient.getDiagnosis() != null) {
        return redirect(routes.DiagnosisController.view(patientId));
    }

    Form<Diagnosis> form = form(Diagnosis.class).bindFromRequest();

    if (form.hasErrors()) {
        form.reject("Diagnosis has not been created");
        return badRequest(create.render(patient, form));
    }

    Diagnosis obj = form.get();
    obj.setPatient(patient);

    if (!form.hasErrors()) {
        // Add soft validation errors to the form
        for (Entry<String, String> e : obj.getSoftValidationErrors().entrySet()) {
            form.reject(e.getKey(), e.getValue());
        }
        if (form.hasErrors()) {
            form.reject("Diagnosis has not been created");
            return badRequest(create.render(patient, form));
        }
    }

    obj.save();
    audit.logCreate(obj.getId(), obj);
    return redirect(routes.DiagnosisController.view(patientId));
}
公共静态结果保存(长TID){
Patient-Patient=Ebean.find(Patient.class,patientId);
如果(患者==null){
闪光(“错误”,“患者不存在”);
返回PatientController.home();
}
if(patient.getDiagnosis()!=null){
返回重定向(routes.DiagnosisController.view(patientId));
}
表单=表单(Diagnosis.class).bindFromRequest();
if(form.hasErrors()){
拒绝(“尚未创建诊断”);
返回badRequest(创建、呈现(患者、表单));
}
诊断对象=form.get();
对象:患者(患者);
如果(!form.hasErrors()){
//向表单中添加软验证错误
对于(条目e:obj.getSoftValidationErrors().entrySet()){
拒绝(e.getKey(),e.getValue());
}
if(form.hasErrors()){
拒绝(“尚未创建诊断”);
返回badRequest(创建、呈现(患者、表单));
}
}
obj.save();
logCreate(obj.getId(),obj);
返回重定向(routes.DiagnosisController.view(patientId));
}

我不知道为什么会产生两次诊断,可能是一些同步问题?需要帮助

我假设这是对现有诊断对象的检查:

if (patient.getDiagnosis() != null) {
    return redirect(routes.DiagnosisController.view(patientId));
}
这是创建和插入新诊断对象的代码:

Diagnosis obj = form.get();
...
obj.save();
发生的情况是两个POST请求同时执行。您的代码在两个不同的线程中同时运行请求。两个线程都运行检查以查看诊断是否存在,并且都发现它不存在。然后,两个线程将新的诊断对象保存到数据库中

这称为a,其原因是两个线程同时读取和写入同一对象。通过使用将诊断检查和诊断创建代码分组到一个工作单元中,可以使代码正常工作


有关使用Ebean在用事务的更多信息,请参见此处的事务操作:

我假设这是对现有诊断对象的检查:

if (patient.getDiagnosis() != null) {
    return redirect(routes.DiagnosisController.view(patientId));
}
这是创建和插入新诊断对象的代码:

Diagnosis obj = form.get();
...
obj.save();
发生的情况是两个POST请求同时执行。您的代码在两个不同的线程中同时运行请求。两个线程都运行检查以查看诊断是否存在,并且都发现它不存在。然后,两个线程将新的诊断对象保存到数据库中

这称为a,其原因是两个线程同时读取和写入同一对象。通过使用将诊断检查和诊断创建代码分组到一个工作单元中,可以使代码正常工作


有关使用Ebean在用事务的更多信息,请参见此处的事务操作:

我假设这是对现有诊断对象的检查:

if (patient.getDiagnosis() != null) {
    return redirect(routes.DiagnosisController.view(patientId));
}
这是创建和插入新诊断对象的代码:

Diagnosis obj = form.get();
...
obj.save();
发生的情况是两个POST请求同时执行。您的代码在两个不同的线程中同时运行请求。两个线程都运行检查以查看诊断是否存在,并且都发现它不存在。然后,两个线程将新的诊断对象保存到数据库中

这称为a,其原因是两个线程同时读取和写入同一对象。通过使用将诊断检查和诊断创建代码分组到一个工作单元中,可以使代码正常工作


有关使用Ebean在用事务的更多信息,请参见此处的事务操作:

我假设这是对现有诊断对象的检查:

if (patient.getDiagnosis() != null) {
    return redirect(routes.DiagnosisController.view(patientId));
}
这是创建和插入新诊断对象的代码:

Diagnosis obj = form.get();
...
obj.save();
发生的情况是两个POST请求同时执行。您的代码在两个不同的线程中同时运行请求。两个线程都运行检查以查看诊断是否存在,并且都发现它不存在。然后两个线程都保存一个新的dia