我正在尝试从EJB3 JTA JPA(EclipseLink)迁移应用程序 . 目前,该应用程序利用应用程序管理的持久上下文,因为设计时间数据库数量未知 .
应用程序管理的持久化上下文允许我们控制如何创建EntityManager(例如 supply different datasources JNDI to create proper EntityManager for specific DB on runtime ) .
例如 .
Map properties = new HashMap();
properties.put(PersistenceUnitProperties.TRANSACTION_TYPE, "JTA");
//the datasource JNDI is by configuration and without prior knowledge about the number of databases
//currently, DB JNDI are stored in a externalized file
//the datasource is setup by operation team
properties.put(PersistenceUnitProperties.JTA_DATASOURCE, "datasource-jndi");
properties.put(PersistenceUnitProperties.CACHE_SHARED_DEFAULT, "false");
properties.put(PersistenceUnitProperties.SESSION_NAME, "xxx");
//create the proper EntityManager for connect to database decided on runtime
EntityManager em = Persistence.createEntityManagerFactory("PU1", properties).createEntityManager();
//query or update DB
em.persist(entity);
em.createQuery(...).executeUpdate();
当部署在EJB容器(例如WebLogic)中时,使用适当的TransactionAttribute(例如TransactionAttributeType.REQUIRED),容器将负责事务的开始/结束/回滚 .
现在,我正在尝试将此应用程序迁移到Spring Boot . 我遇到的问题是,即使在使用 @Transactional(propagation = Propagation.REQUIRED)
注释方法后也没有启动事务 .
Spring应用程序打包为 an executable JAR file 并使用embadded Tomcat运行 .
当我尝试执行这些更新API时,例如 EntityManager.persist(..)
,EclipseLink总是抱怨:
javax.persistence.TransactionRequiredException:'当前没有事务处于活动状态'
示例代码如下:
//for data persistence
@Service
class DynamicServiceImpl implements DynamicService {
//attempt to start a transaction
@Transactional(propagation = Propagation.REQUIRED)
public void saveData(DbJndi, EntityA){
//this return false that no transaction started
TransactionSynchronizationManager.isActualTransactionActive();
//create an EntityManager based on the input DbJndi to dynamically
//determine which DB to save the data
EntityManager em = createEm(DbJndi);
//save the data
em.persist(EntityA);
}
}
//restful service
@RestController
class RestController{
@Autowired
DynamicService service;
@RequestMapping( value = "/saveRecord", method = RequestMethod.POST)
public @ResponseBody String saveRecord(){
//save data
service.saveData(...)
}
}
//startup application
@SpringBootApplication
class TestApp {
public static void main(String[] args) {
SpringApplication.run(TestApp.class, args);
}
}
persistence.xml
-------------------------------------------
<persistence-unit name="PU1" transaction-type="JTA">
<properties>
<!-- comment for spring to handle transaction??? -->
<!--property name="eclipselink.target-server" value="WebLogic_10"/ -->
</properties>
</persistence-unit>
-------------------------------------------
application.properties (just 3 lines of config)
-------------------------------------------
spring.jta.enabled=true
spring.jta.log-dir=spring-test # Transaction logs directory.
spring.jta.transaction-manager-id=spring-test
-------------------------------------------
我的使用模式不遵循大多数典型用例(例如,使用已知数量的DB - Spring + JPA + multiple persistence units: Injecting EntityManager) .
有人可以就如何解决这个问题给我建议吗?
有没有人曾经遇到这种情况,DB在设计时间内不为人所知?
谢谢 .