用例是发送带有由MDB处理的GPS信息的JMS消息的设备。如果数据库中不存在设备,则创建/插入设备并创建/插入GPS记录。在发送消息时处理消息时一切正常。当来自同一设备的消息建立并在彼此的毫秒内处理时,会出现此问题。似乎存在一个JMS消息进程在另一个JMS进程检查实体(并且它不存在)并尝试插入实体(并且它已经存在)之间插入实体的竞争条件。
该进程正在尝试多次插入Device实体,因为在某些时候进程发现没有记录存在。抛出以下异常,因为正在处理的上一条消息已插入记录。我已经尝试将IsolationLevels更改为每个值,直到SERIALIZABLE,没有运气。任何想法将不胜感激! WAS 7,OpenJPA 2.0.2,EJB3.0
[8/30/12 11:14:01:319 EDT] 0000002a RegisteredSyn E WTRN0074E: Exception caught
from before_completion synchronization operation:
<openjpa-2.0.2-SNAPSHOT-r422266:1295351 fatal store error>
org.apache.openjpa.persistence.EntityExistsException: The transaction has been
rolled back. See the nested exceptions for details on the errors that occurred.
Caused by: <openjpa-2.0.2-SNAPSHOT-r422266:1295351 fatal store error>
org.apache.openjpa.persistence.EntityExistsException: ORA-00001:
unique constraint (SPW_OWN.PK_DEVICE) violated
执行此过程的SSB代码段:
Device device = deviceManager.findDeviceByDeviceI(deviceString);
//check to see if device entity exists
if(device == null){
Log.logDebug(this, "device " + deviceString +" is null");
device.setDeviceI(deviceString);
//tried both create and update with no luck
//deviceManager.createDevice(device);
deviceManager.updateDevice(device);
}
JPA SSB:
@Action(Action.ACTION_TYPE.UPDATE)
public String updateDevice(Device device) throws Exception {
EntityManager em = getEntityManager();
try {
device = em.merge(device);
} finally {
em.close();
}
return "";
}
做一些测试我已经找到了一个体面的工作虽然我仍然不是100%满意。欢迎任何其他建议:
我通常不喜欢将异常捕获用作控制流。我还想象有一种方法可以将JMS MDB保持为容器管理事务,并让Java EE服务器重新处理该消息。