【发布时间】:2014-05-13 22:35:05
【问题描述】:
我有一个与 hibernate 交互的 java servlet。因此有必要在系统上生成一个检查 ID:
for (long j = 0; j < soldProductQuantity.longValue(); j++) {
checkId = Hotel.getNextMcsCheckAndIncrement();
checkIdString = checkId.toString();
McsCheck.generateCheck(checkIdString);
}
getNextMcsCheckAndIncrement() 定义为
static public synchronized Long getNextMcsCheckAndIncrement()
它使用休眠从数据库中提取一个值,对其进行一些操作,将修改后的值存储回来,然后返回数字。
因为getNextMcsCheckAndIncrement 是同步的,我希望没有两个检查具有相同的编号,因为没有两个线程可以同时进入该方法。
但我可以在我的数据中看到多个支票 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();
}
是的,我知道这不是最好的方法,我会及时解决。但最直接的问题是为什么并发会失败。
【问题讨论】:
-
(您可以更改您的个人资料以添加您的姓名。不要在问题中添加感谢和签名,这是噪音。)
-
@user3634440 编辑您的帖子,而不是将代码放入 cmets。
-
注明。刚刚解决了这个问题,并将删除有问题的评论。帖子已更新。
-
你能告诉我们
returnAllObjects方法吗? -
大卫华莱士:是的,刚刚更新。
标签: java hibernate servlets synchronization