当前位置: 首页 > 知识库问答 >
问题:

使用应用程序管理持久性上下文的Spring Boot

闾丘博超
2023-03-14

应用程序管理的持久性上下文允许我们控制如何创建EntityManager(例如,提供不同的数据源JNDI以在运行时为特定的DB创建适当的EntityManager)。

例如。

    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)时,容器将负责事务的开始/结束/回滚。

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
    -------------------------------------------

我的使用模式并不遵循大多数典型的用例(例如,已知数量的DBS-Spring+JPA+多个持久性单元:注入EntityManager)。

共有1个答案

梅跃
2023-03-14

您自己基本上已经回答了这个问题:“当部署在EJB容器(例如WebLogic)中,使用适当的TransactionAttribute(例如TransactionAttributeType.Required)时,容器将负责事务的开始/结束/回滚”。

WebLogic符合Java Enterprise Edition规范,这可能是它以前工作的原因,但现在您使用的是Tomcat(嵌入式模式),而不是。所以你不能做你想做的事。persistence.xml文件中的以下语句:

需要企业服务器(WebLogic,Glassfish,JBoss等)

对于Tomcat,您只能执行以下操作:

myEntityManager.getTransaction.begin();
... //Do your transaction stuff
myEntityManager.getTransaction().commit();
 类似资料:
  • 实际上,我使用野飞JEE服务器并考虑切换到Quarkus。关于quarkus,我有以下问题: 1.坚持。xml 我看到夸克斯使用自己的来建立数据库。我可以用来代替吗? 2.容器管理的持久性 quarkus是否提供了类似的功能,还是我必须自己管理持久性?

  • 我有一个nodejs应用程序,它只不过是一个使用微软botbuilder框架构建的机器人。我创建了azure应用程序服务来托管此应用程序。我想找到一种方法,将所有应用程序日志和web服务器日志(如果可能的话)持久化到某个持久化存储中。就像本地web应用程序一样,我们可以在应用程序服务器上查找日志 在做了一些研究之后,我找到了微软关于这方面的官方文件,但看起来它有以下局限性。 我们不能使用应用程序服

  • 问题内容: 我是Java世界和JPA的新手。我在学习JPA时遇到了许多新术语,例如Entity,persistence。在阅读时,我无法理解 Persistence Context 的确切定义。 谁能用简单的外行术语解释它?与中使用的数据有什么关系? 例如,我发现此定义太复杂而难以理解: 持久性上下文是一组实体,因此对于任何持久性标识,都有一个唯一的实体实例。 问题答案: 持久性上下文处理一组实体

  • 持久性上下文是一组实体,因此对于任何持久性标识都有一个唯一的实体实例。

  • 有一种方法可以绕过持久性上下文,只将实体用作数据库表的包装器?

  • 问题内容: 我有一个Spring应用程序,到目前为止运行良好。现在,我希望属性文件位于外部配置文件夹中,而不是在打包的jar中,而无需重新打包即可更改内容。这就是我得到的: 问题答案: 如果将其放置在名为spring的目录中的类路径中的某个位置(相应地更改名称/目录),则可以使用 这将指向web-inf / classes / config / springcontext.properties