java同步方法在servlet中失败
我有一个与hibernate交互的Javaservlet。有必要在系统上生成检查id,因此: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
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();
}