单例EJB、JPA并发访问
我有一个MDB,它调用Singleton EJB来使用JPA维护hourlyTotals。我收到StaleObjectStateException:行已被另一个事务更新或删除 实体Bean代码单例EJB、JPA并发访问,jpa,singleton,ejb,Jpa,Singleton,Ejb,我有一个MDB,它调用Singleton EJB来使用JPA维护hourlyTotals。我收到StaleObjectStateException:行已被另一个事务更新或删除 实体Bean代码 @Entity @Table(name = "hour_db") public class HourlyTotalEntity { @Id private Date transactionTime; @Column(name="success_count") privat
@Entity
@Table(name = "hour_db")
public class HourlyTotalEntity {
@Id
private Date transactionTime;
@Column(name="success_count")
private long successCount;
@Version int version;
public Date getTransactionTime() {
return transactionTime;
}
public void setTransactionTime(Date transactionTime) {
this.transactionTime = transactionTime;
}
public void setSuccessCount(long successCount)
{
this.successCount = successCount;
}
public long getSuccessCount()
{
return successCount;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
EJB代码
@Singleton
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
@Lock(LockType.READ)
public class HourlyTotalEJB {
@PersistenceContext (unitName="DashboardJPA")
private EntityManager em;
public void create(Date transactionTime) throws Exception
{
transactionTime = trim(transactionTime);
HourlyTotalEntity entity = em.find(HourlyTotalEntity.class, transactionTime,LockModeType.OPTIMISTIC_FORCE_INCREMENT);
if(entity == null)
{
entity = new HourlyTotalEntity();
entity.setTransactionTime(transaction);
entity.setSuccessCount(0);
}
entity.setAuthSuccessCount(entity.getAuthSuccessCount() + 1);
em.persist(entity);
em.flush();
em.clear();
}
private Date trim(Date date)
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.MILLISECOND, 0);
calendar.set(Calendar.SECOND, 0);
return calendar.getTime();
}
}
MDB调用onMessage(Message Message)方法上的create(transactionTime)。在大量事务处理期间,MDB将并发调用方法create(TransactionTime),并导致StaleObjectStateException:行被另一个事务更新或删除
如何解决上述问题?您使用的是,这允许多个线程同时调用该方法。由于create
方法不是只读的,因此应该使用写锁。如果使用的是,则允许多个线程同时调用该方法。由于create
方法不是只读的,因此应该改用写锁