Spring @Transactional commit failures ; Deby + Eclipselink Spring @Transactional commit failures ; Deby + Eclipselink spring spring

Spring @Transactional commit failures ; Deby + Eclipselink


Derby locks single rows for INSERT statements, holding each row until the transaction is committed. (If there is an index associated with the table, the previous key is also locked.)

So for your problem, my understanding is your tried to INSERT two records to Derby in one transaction, so when your execute create(peTxn); the derby locks single rows and holding each row until the transaction is committed [ lockA ], then you try to execute create(fcTxn), it will try to obtain another single-row lock to INSERT a new record, but actually the transaction is not committed so the locks still holed [ lockA ].

So the solution is

call getEntityManager().refresh the transaction to commit the transaction when the first step finished. this will focus the SQL INSERT to database.

and suggest to use @Transactional in the service layer.


The problem was due to PersistenceContextType.EXTENDED. I did two changes and problem got resolved.

  1. PersistenceContextType.EXTENDED changed to PersistenceContextType.TRANSACTION
  2. @Singleton changed to @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)@Componentpublic class RWTransactionDao {    @PersistenceContext(type = PersistenceContextType.TRANSACTION)    private EntityManager em;    @Override    protected EntityManager getEntityManager() {        return em;    }    @Transactional    public void createOrderTxns(RWRetailTransaction peTxn, RWRetailTransaction fcTxn) {        create(peTxn);        create(fcTxn);        log.debug("Committed Transaction : {} ", peTxn.displayString());        log.debug("Committed Transaction : {} ", fcTxn.displayString());    }    @Transactional    public void create(T entity) {        getEntityManager().persist(entity);    }