如何通过获取不受对象管理器

时间:2017-11-12 21:47:56

标签: java spring google-app-engine jpa datanucleus

我有需要的业务逻辑

1)执行一些操作,如count或'查找前1项的id大于a的字段',即对实体A执行一些读取操作。计数或查找涉及超过25个项目,因此它会生成许多实体组被影响。 2)然后对另一个实体B执行一些操作并持久保存已更改的实体 3)现在我改变了实体A的唯一对象并希望保留它

如果我没有在我的方法上使用Spring @Transactional,我得到了ID为“A @ someHash”的Object在调用3)时由另一个对象管理器管理。 АссordingtoSystem.out.println(NucleusJPAHelper.getObjectState(busRouteToCheck));对象处于持久状态

如果我使用Spring @Transactional放置整个方法,我得到“在单个事务中打开了太多实体组”

我如何强制结果1)不被对象管理器管理,最终得到一些Long值和进程3)就像我第一次在我的方法中处理A一样。最后,我需要读取多个实体组的项目,并且只需要在事务中更新两个实体组。

我试图解决的问题:1)将整个方法分为3个,其中2个没有@Transaction,1个和3个有@Transaction;在这里我还有NucleusUserException; 2)在相同条件下,我尝试使用2个不同的事务管理器,首先调用只读调用(方法1),然后用第二个调用(方法3)。

是否有任何明确的方法来管理对象管理器?

使用的Dependenciies是:

   <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-api-jdo</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-api-jpa</artifactId>
            <version>3.1.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.appengine.orm</groupId>
            <artifactId>datanucleus-appengine</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.datanucleus</groupId>
            <artifactId>datanucleus-core</artifactId>
            <version>3.1.1</version>
        </dependency>

和增强器插件是

  <plugin>
                <groupId>org.datanucleus</groupId>
                <artifactId>maven-datanucleus-plugin</artifactId>
                <version>3.1.3</version>
                <configuration>
                    <!-- Make sure this path contains your persistent classes! -->
                    <!--<mappingIncludes>**/domain/*.class</mappingIncludes>-->
                    <!--<persistenceUnitName>transactions-optional</persistenceUnitName>-->
                    <verbose>true</verbose>
                    <api>JPA</api>
                    <!--<mappingIncludes>com/appspot/Player.class</mappingIncludes>-->
                    <!--<metadataIncludes>com/appspot/Player.class</metadataIncludes>-->
                    <fork>false</fork>
                </configuration>
                <executions>
                    <execution>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>enhance</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <!--<dependency>
                        <groupId>asm</groupId>
                        <artifactId>asm-commons</artifactId>
                        <version>3.3.1</version>
                    </dependency>-->
                    <dependency>
                        <groupId>org.datanucleus</groupId>
                        <artifactId>datanucleus-api-jpa</artifactId>
                        <version>3.1.1</version>
                    </dependency>
                    <dependency>
                        <groupId>org.datanucleus</groupId>
                        <artifactId>datanucleus-core</artifactId>
                        <version>3.1.1</version>
                    </dependency>
                    <dependency>
                        <groupId>org.datanucleus</groupId>
                        <artifactId>datanucleus-enhancer</artifactId>
                        <version>3.1.1</version>
                    </dependency>
                </dependencies>
            </plugin>

1 个答案:

答案 0 :(得分:1)

我不能说我已经详细了解谷歌JPA实施中发生的事情,并获得了我发布的例外情况。相反,我已经解决了我面临的全球性问题。我相信如果处理异常,你也面临同样的问题。我试图解决在事务中更改一些次要对象的限制以及不需要事务的可能对象的读取(因为事务更新由于上述异常而没有失败)。

问题在架构上得到解决:1)您应该在服务层中创建单独的方法来读取实体或获取计数而不使它们成为事务2)在服务层中创建单独的方法,将非事务方法的结果作为参数获取并更新实体;使这些方法在控制器层或控制器下面的自定义层中进行事务处理,但在服务上方分别调用这些方法!

我的错是我认为Spring的@Transactional注释有意义,即使使用@Transactionl从另一个方法调用@Transactional的方法也是如此。这是错误的:由于注释的Aspect性质,只有从外部类对象调用方法时才有意义。因此,在我的示例中,我将整个调用放在唯一的事务中(具有太多实体异常)或者在非事务内(因此获取具有id的Object ...由不同的对象管理器管理)。因此,将非事务行为和事务行为分离到不同的方法并从外部调用它们对我有帮助。