以下是spring config
日期来源
WebView
实体经理配置
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${rwos.dataSource.driverClassName}" />
<property name="url" value="${rwos.dataSource.url}" />
<property name="username" value="${rwos.dataSource.user}" />
<property name="password" value="${rwos.dataSource.password}" />
</bean>
以下是用于保留实体
的代码段<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="persistenceUnitManager" class="org.springframework.data.jpa.support.MergingPersistenceUnitManager">
<property name="defaultDataSource" ref="dataSource"/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="persistenceUnitManager"/>
<property name="persistenceUnitName" value="com.retailwave.rwos_rwos-data-pojo_jar_4.0.0PU"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" lazy-init="true">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
<property name="dataSource" ref="dataSource" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
</beans>
班级:
@Singleton
@Component
public class RWTransactionDao {
@PersistenceContext(type = PersistenceContextType.EXTENDED)
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);
}
}
记录消息:
@Component
@Path("/")
public class RWTransactionREST {
@Inject
private RWTransactionDao rWTransactionDao;
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("txns/sales")
public RWResponse createPurchaseTransaction(RWRetailTransaction peTxn, RWRetailTransaction fcTxn) {
rWTransactionDao.createOrderTxns(peTxn, fcTxn);
builder.status(RWStatus.OK);
RWResponse response = builder.build();
log.info("Returning.. {}", response);
return response;
}
}
在一段时间后,在其他一些REST实现方法中,同一个RWTransactionDao中发生了以下错误
2017-06-14 10:49:51,453 DEBUG [qtp592179046-13] - Committed Transaction : RWRetailTransaction[609, CU_ORD, RTCO-609-17-11193, 2017-06-14 10:49:51.431]
2017-06-14 10:49:51,453 DEBUG [qtp592179046-13] - Committed Transaction : RWRetailTransaction[509, CU_ORD, RTCO-509-17-11193, 2017-06-14 10:49:51.444]
2017-06-14 10:49:51,463 INFO [qtp592179046-13] RWTransactionREST - Returning.. Response[1000:Order has been created successfully, Transaction Id : RTCO-609-17-11193]
由于此错误,先前的提交已回滚但不应该回滚。
不确定导致此次回滚的原因。
答案 0 :(得分:3)
Derby为INSERT语句锁定单行,保持每一行直到提交事务。 (如果存在与表关联的索引,则前一个键也会被锁定。)
所以对于你的问题,我的理解是你试图在一个事务中 INSERT 两个记录到Derby,所以当你执行create(peTxn);
时,derby锁定单行并保持每一行直到事务已提交[lockA],然后您尝试执行create(fcTxn)
,它将尝试获取另一个单行锁到 INSERT 一条新记录,但实际上事务没有提交,因此锁仍然锁定[lockA]。
所以解决方案是
调用getEntityManager().refresh
事务以在第一步完成时提交事务。这将把SQL INSERT的重点放在数据库上。
并建议在服务层使用@Transactional
。
答案 1 :(得分:0)
问题归因于PersistenceContextType.EXTENDED
。我做了两处改动,问题得到解决。
PersistenceContextType.EXTENDED
已更改为PersistenceContextType.TRANSACTION
@Singleton
已更改为@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
public 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);
}