每次调用方法时,我都想从我的域对象(表)ID中获得唯一的ID。这样就不会重复ID。我有一个返回唯一ID的函数。
public static Long generateID (Short company)
throws Exception
{
IDDAO iDDAO = SpringApplicationContext.getBean (IDDAO.class);
ID iD = iDDAO.findByNaturalKey (new IDNatKey (company);
if (iD != null)
{
// Check if ID has reached limit, then reset the ID to the first ID
if (iD.getLatestIDno ().longValue () == iD.getLastIDno ().longValue ())
{
iD.setLatestIDno (iD.getFrstIDno ());
}
// Get next ID
iD.setLatestIDno (iD.getLatestIDno () + 1);
// update database with latest id
iDDAO.update (iD);
return iD.getLatestIDno ();
}
}
问题是,如果从两台计算机访问应用程序并从UI按下按钮以完全同时生成ID,则有时此方法返回的ID重复
例如
Long ID = TestClass.generateID (123);
这有时会给我重复。
我做了这样的方法
public static synchronized Long generateID (Short company)
throws Exception
因此一次只能有一个线程可以使用此功能,但是仍然存在重复的问题。
我不希望使用数据库序列,因为如果事务回滚,我不希望ID序列中存在间隙,在这种情况下,序列仍将递增,这是我不希望的。中间的间隙可以但不能结束。例如,我们有1、2和3作为ID,然后有2个回滚,这是可以的。但是如果3回滚,我们应该在另一个用户到来时再次获得3,如果有序列,它将给出4
请帮我告诉我我做错了什么吗?静态同步还会导致其他线程同时进入该函数吗?我在该类中还有许多其他静态(但不同步)功能。如果我将其静态同步,这也会对他们造成问题吗?
谢谢
艾登
最佳答案
保留2个唯一ID:
从数据库中分配两者-最好将所有共享状态都保留在那里,因为数据库将保证ACID,而Java并发性则很棘手。