【问题标题】:Database insertion synchronization数据库插入同步
【发布时间】:2015-08-11 12:42:01
【问题描述】:

我有一个java代码,它根据从数据库接收到的数据生成一个请求号,然后更新数据库以获取新生成的数据

synchronized (this.getClass()) {
            counter++;
            System.out.println(counter);
            System.out.println("start " + System.identityHashCode(this));
            certRequest
                    .setRequestNbr(generateRequestNumber(certInsuranceRequestAddRq
                            .getAccountInfo().getAccountNumberId()));
            System.out.println("outside funcvtion"+certRequest.getRequestNbr());
            reqId = Utils.getUniqueId();
            certRequest.setRequestId(reqId);
            System.out.println(reqId);
            ItemIdInfo itemIdInfo = new ItemIdInfo();

            itemIdInfo.setInsurerId(certRequest.getRequestId());

            certRequest.setItemIdInfo(itemIdInfo);

            dao.insert(certRequest);
            addAccountRel();
            counter++;
            System.out.println(counter);
            System.out.println("end");

        }

System.out.println() 语句的输出是 `

1
start 27907101
com.csc.exceed.certificate.domain.CertRequest@a042cb
inside function request number66
outside funcvtion66
AF88172D-C8B0-4DCD-9AC6-12296EF8728D

2
end
3
start 21695531
com.csc.exceed.certificate.domain.CertRequest@f98690
inside function request number66
outside funcvtion66
F3200106-6033-4AEC-8DC3-B23FCD3CA380

4
end

在我的情况下,我收到了来自两个线程的调用此代码。

如果您观察到两个线程独立运行。但是,两种情况下请求编号的数据是相同的。

是否有可能在第一个线程的数据库更新完成之前,第二个线程开始执行。 ` generateRequestNumber() 的代码如下:

public String generateRequestNumber(String accNumber) 抛出异常 {

String requestNumber = null;

if (accNumber != null) {

    String SQL_QUERY = "select CERTREQUEST.requestNbr from CertRequest as CERTREQUEST, "
            + "CertActObjRel  as certActObjRel where  certActObjRel.certificateObjkeyId=CERTREQUEST.requestId "
            + " and certActObjRel.certObjTypeCd=:certObjTypeCd "
            + " and certActObjRel.certAccountId=:accNumber ";

    String[] parameterNames = { "certObjTypeCd", "accNumber" };
    Object[] parameterVaues = new Object[] {
            Constants.REQUEST_RELATION_CODE, accNumber };
    List<?> resultSet = dao.executeNamedQuery(SQL_QUERY,
            parameterNames, parameterVaues);

    // List<?> resultSet = dao.retrieveTableData(SQL_QUERY);
    if (resultSet != null && resultSet.size() > 0) {
        requestNumber = (String) resultSet.get(0);
    }

    int maxRequestNumber = -1;

    if (requestNumber != null && requestNumber.length() > 0) {
        maxRequestNumber = maxValue(resultSet.toArray());
        requestNumber = Integer.toString(maxRequestNumber + 1);

    } else {
        requestNumber = Integer.toString(1);
    }
    System.out.println("inside function request number"+requestNumber);
    return requestNumber;
}
return null;

}

【问题讨论】:

    标签: java multithreading hibernate


    【解决方案1】:

    数据库允许多个同时连接,因此除非您正确编写代码,否则可能会弄乱数据。

    由于您似乎只需要一个唯一的增长整数,您可以轻松地在数据库中安全地生成一个,例如一个序列(如果数据库支持)。不支持序列的数据库通常会提供一些其他方式(例如 MySQL 中的自动递增列)。

    【讨论】:

    • 我明白你的意思,但是我不仅需要唯一的增长整数,首先我需要更新两个数据库表,然后基于该更新再次生成下一个数字。
    • @pkn1230 在您的示例中,66 后面的数字是 67。在生成该数字时听起来没有太多逻辑。
    • 请忽略它,这是一个旧输出。
    • 好吧,您可能想修改您的generateRequestNumber,使其成为线程安全的。您显示的代码并没有真正说明任何事情。你遗漏了所有的实际实现。
    • 我想我有事务同步问题。
    猜你喜欢
    • 1970-01-01
    • 2018-10-03
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-04
    • 1970-01-01
    相关资源
    最近更新 更多