我正在尝试从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
    -------------------------------------------

    &ltpersistence-unit name="PU1" transaction-type="JTA">

        &ltproperties>

            <!-- 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在设计时间内不为人所知?

谢谢 .