Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.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
java同步方法在servlet中失败_Java_Hibernate_Servlets_Synchronization - Fatal编程技术网

java同步方法在servlet中失败

java同步方法在servlet中失败,java,hibernate,servlets,synchronization,Java,Hibernate,Servlets,Synchronization,我有一个与hibernate交互的Javaservlet。有必要在系统上生成检查id,因此: for (long j = 0; j < soldProductQuantity.longValue(); j++) { checkId = Hotel.getNextMcsCheckAndIncrement(); checkIdString = checkId.toString(); McsCheck.generateCheck(che

我有一个与hibernate交互的Javaservlet。有必要在系统上生成检查id,因此:

for (long j = 0; j < soldProductQuantity.longValue(); j++) {
    checkId = Hotel.getNextMcsCheckAndIncrement();                  
    checkIdString = checkId.toString();
    McsCheck.generateCheck(checkIdString);                                  
}
它使用hibernate从数据库中提取一个值,对其执行一些操作,存储修改后的值,然后返回数字

因为getNextMCCHECKANDIncrement是同步的,所以我希望没有两个检查具有相同的编号,因为没有两个线程可以同时进入该方法

然而,我可以在数据中看到多个检查ID的重复实例。很明显,这是行不通的。我错过了什么

getNext的实现如下所示:

// Increment FIRST, then return the resulting value as the current MCS check value.
static public synchronized Long getNextMcsCheckAndIncrement() {
    Hotel theHotel = null; 
    Long checkCounter; 
    @SuppressWarnings("unchecked")                  
    List<Hotel> hotelList = Hotel.returnAllObjects(); 
    for (Hotel currentHotel : hotelList) {  // there should be only one. 
                theHotel = currentHotel;
        }

    checkCounter = theHotel.getMcsCheckCounter()+1; 
    theHotel.setMcsCheckCounter(checkCounter);
    theHotel.update(); 
    return checkCounter; 

} 

static public List returnAllObjects() {
    return Hotel.query ("from Hotel"); 
}   

static public List query(String queryString) {
    Session session = HibernateUtil.getSessionFactory().openSession();
    List result = session.createQuery(queryString).list();  
    session.close(); 
    return result;
}

public void update() {
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction transaction = session.beginTransaction();
    session.update(this);
    transaction.commit();
    session.close(); 
}

是的,我知道这不是最好的办法,我会及时解决的。但眼前的问题是为什么并发会失败

匿名评论给出了正确答案:问题一定是hibernate数据库中的Hotel对象,而不是同步方法。尽管计数器方法已正确同步,但如果在该算法之外修改hotel对象,则这些访问将不会同步


因此,正确的答案是仔细检查对hotel对象的所有数据库访问,并确保在进行此循环时不会在其他地方修改该对象,或者将hotel对象中的计数器重构为专用存储

您可以更改您的个人资料以添加您的姓名。不要在问题中添加感谢和签名,这是噪音。@user3634440编辑您的帖子,而不是在评论中放置代码。注意。刚刚解决了这个问题,并将删除冒犯性的评论。帖子已经更新了。你能给我们看看returnAllObjects方法吗?大卫·华莱士:是的,刚刚更新。
// Increment FIRST, then return the resulting value as the current MCS check value.
static public synchronized Long getNextMcsCheckAndIncrement() {
    Hotel theHotel = null; 
    Long checkCounter; 
    @SuppressWarnings("unchecked")                  
    List<Hotel> hotelList = Hotel.returnAllObjects(); 
    for (Hotel currentHotel : hotelList) {  // there should be only one. 
                theHotel = currentHotel;
        }

    checkCounter = theHotel.getMcsCheckCounter()+1; 
    theHotel.setMcsCheckCounter(checkCounter);
    theHotel.update(); 
    return checkCounter; 

} 

static public List returnAllObjects() {
    return Hotel.query ("from Hotel"); 
}   

static public List query(String queryString) {
    Session session = HibernateUtil.getSessionFactory().openSession();
    List result = session.createQuery(queryString).list();  
    session.close(); 
    return result;
}

public void update() {
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction transaction = session.beginTransaction();
    session.update(this);
    transaction.commit();
    session.close(); 
}