我在我的方法上调用多线程时遇到问题,这些线程不能同时调用该方法,因为我在同步块中调用该方法,但每次线程都离开下一步进行的阻止。
被调用的方法使用我的实体ID(二进制)调用em.find(Class<T> entityClass, Object primaryKey)
,如果该对象存在于我的数据库中,我更新它并为了持久性目的而调用merge()
,如果它没有'存在我用我的id创建一个新的,并调用merge()
将其保存在我的数据库中,在我的情况下,我调用所有具有相同BinaryFile对象的线程,并且此BinaryFile的id不存在于我的数据库。
预期的行为是:
merge()
在我的数据库中更新。真正发生的事情:
我得到了这个例外:
org.hibernate.exception.ConstraintViolationException: ORA-00001: unique constraint (SCOM_DEV2.BINARY_ID_PK) violated
org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:74)
org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:125)
org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:110)
org.hibernate.engine.jdbc.internal.proxy.AbstractStatementProxyHandler.continueInvocation(AbstractStatementProxyHandler.java:129)
org.hibernate.engine.jdbc.internal.proxy.AbstractProxyHandler.invoke(AbstractProxyHandler.java:81)
sun.proxy.$Proxy57.executeUpdate(Unknown Source)
org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:56)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2849)
org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3290)
org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:80)
org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264)
org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186)
org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326)
org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081)
org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315)
org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104)
org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53)
com.arjuna.ats.internal.jta.resources.arjun
调用方法的代码段
CreateOrUpdate(BinaryFile binaryFile){
Binary b = em.find(Binary.class, binarytmp.getId());
if(b==null){
b=new Binary();
b.setID(id);
}
b.setName(binarytmp.getName());
em.merge(b);
}
方法调用的代码段
synchronized(binaryFile.getID().intern()){
CreateOrUpdate(binaryFile);
}
我的实体的代码段
@Entity
@Table(name = "BINARY")
public class Binary implements ScoBinary {
/**
* id field.
*/
@Id
@Column(name = "id")
private String id;
/**
* name of the field
*/
@Column(name = "name")
private String name;
public String getID(){
return this.id;
}
public void setID(String){
return this.id = id;
}
public Stirng getName(){
return this.name;
}
public void setName(Stirng name){
return this.name=name;
}
}
当我用一个线程调用相同的方法时,一切都按预期运行,只有当我用多个线程调用方法时抛出此异常,我试图理解实际发生了什么,并且我发现当第一个线程执行时方法,它创建对象并持久化,但下一个线程在调用find()方法时获取null,尽管第一个线程已经调用merge()将其保存在我的数据库中,我试着调用{{1在我的em.flush()
方法之后不确定对象是在从下一个线程调用find之前保存但是我仍然得到相同的结果,请你启发我。