休眠 |为什么交易"half-committed"
Hibernate | Why is the transaction "half-committed"
我正在 Spring 引导项目中使用 Hibernate。
我有如下一段代码:
public class SomeService {
private Dependency dependency;
@Transactional(readOnly=false)
public void doSomething() {
//some BL code...
dependency.doSomeDbManipualation();
someOperation();
}
public void someOperation() {
//some code that eventually fails
}
}
public class Dependency {
public void doSomeDbManipulation() {
Entity entity = ...; //get the entity from current session by its key
if (entity != null) {
session.delete(entity);
}
OtherEntity oEntity = new OtherEntity();
//set its fields
Long oEntityId = session.save(oEntity);
entity = new Entity();
entity.setForeignKey(oEntityId);
//set other fields
session.persist(entity);
}
}
现在,我在数据库中有一个具有相关键的实体。所以我期望在调用服务时,查找实体的代码确实会找到它。但是由于 someOperation()
失败,我希望在数据库中看不到任何变化。
事实上,在调用 someService.doSomething()
(失败)之后,我查看了数据库,发现现有实体已被删除!但是没有创建新实体(没关系)。
为什么这个交易"half committed"?
编辑:
显然 delete() 和 save() 是立即提交的。当我调试时,我看到在代码中的这一行完成后该实体立即被删除。 OtherEntity
也会立即添加到数据库中。
persist() 不会立即提交。
我使用 AspectJ 进行事务管理。这是我 pom.xml:
的相关部分
<project>
...
<dependencies>
...
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.3</version>
</dependency>
</dependencies>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<outxml>true</outxml>
<forceAjcCompile>true</forceAjcCompile>
<source>1.8</source>
<target>1.8</target>
<Xlint>ignore</Xlint>
<complianceLevel>1.8</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
<preserveAllLocals>true</preserveAllLocals>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<id>AspectJ-Compile</id>
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
</project>
我不知道为什么 aspect j 被显式添加为 pom 中的依赖项 file.if 你使用 spring boot 你会从 box.I 中看到不可预测的行为类路径中存在重复的 jar。
我也无法理解为什么从本身标记为只读事务的方法调用数据库操作方法。
感觉这里设计的不对
我找到了问题的解决方案。
我在几个 类 中有多个 @ComponentScan 注释。当我将它们全部移除并只留下一个时,一切都按预期工作。
我不明白这种奇怪行为的原因,所以我发布了一个单独的问题,here
我正在 Spring 引导项目中使用 Hibernate。
我有如下一段代码:
public class SomeService {
private Dependency dependency;
@Transactional(readOnly=false)
public void doSomething() {
//some BL code...
dependency.doSomeDbManipualation();
someOperation();
}
public void someOperation() {
//some code that eventually fails
}
}
public class Dependency {
public void doSomeDbManipulation() {
Entity entity = ...; //get the entity from current session by its key
if (entity != null) {
session.delete(entity);
}
OtherEntity oEntity = new OtherEntity();
//set its fields
Long oEntityId = session.save(oEntity);
entity = new Entity();
entity.setForeignKey(oEntityId);
//set other fields
session.persist(entity);
}
}
现在,我在数据库中有一个具有相关键的实体。所以我期望在调用服务时,查找实体的代码确实会找到它。但是由于 someOperation()
失败,我希望在数据库中看不到任何变化。
事实上,在调用 someService.doSomething()
(失败)之后,我查看了数据库,发现现有实体已被删除!但是没有创建新实体(没关系)。
为什么这个交易"half committed"?
编辑:
显然 delete() 和 save() 是立即提交的。当我调试时,我看到在代码中的这一行完成后该实体立即被删除。 OtherEntity
也会立即添加到数据库中。
persist() 不会立即提交。
我使用 AspectJ 进行事务管理。这是我 pom.xml:
的相关部分<project>
...
<dependencies>
...
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
...
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.7</version>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.8.3</version>
</dependency>
</dependencies>
<configuration>
<showWeaveInfo>true</showWeaveInfo>
<outxml>true</outxml>
<forceAjcCompile>true</forceAjcCompile>
<source>1.8</source>
<target>1.8</target>
<Xlint>ignore</Xlint>
<complianceLevel>1.8</complianceLevel>
<encoding>UTF-8</encoding>
<verbose>true</verbose>
<preserveAllLocals>true</preserveAllLocals>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<id>AspectJ-Compile</id>
<phase>process-classes</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
</project>
我不知道为什么 aspect j 被显式添加为 pom 中的依赖项 file.if 你使用 spring boot 你会从 box.I 中看到不可预测的行为类路径中存在重复的 jar。
我也无法理解为什么从本身标记为只读事务的方法调用数据库操作方法。
感觉这里设计的不对
我找到了问题的解决方案。 我在几个 类 中有多个 @ComponentScan 注释。当我将它们全部移除并只留下一个时,一切都按预期工作。
我不明白这种奇怪行为的原因,所以我发布了一个单独的问题,here