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

Spring Boot+Spring Data JPA+事务不能正常工作

伊光赫
2023-03-14
@Entity
class Person
{
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    private String name;
    //setters & getters
}

@Repository
public interface PersonRepository extends JpaRepository<Person, Integer>{

}


import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
class PersonService
{
    @Autowired PersonRepository personRepository;

    @Transactional
    void save(List<Person> persons){
        for (Person person : persons) {         
            if("xxx".equals(person.getName())){
                throw new RuntimeException("boooom!!!");
            }
            personRepository.save(person);          
        }
    }
}
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
public class ApplicationTests {

    @Autowired
    PersonService personService;

    @Test
    public void test_logging() {
        List<Person> persons = new ArrayList<Person>();
        persons.add(new Person(null,"abcd"));
        persons.add(new Person(null,"xyz"));
        persons.add(new Person(null,"xxx"));
        persons.add(new Person(null,"pqr"));

        personService.save(persons);
    }

}

这里的期望是它不应该在PERSON表中插入任何记录,因为它会在插入第三个PERSON对象时抛出异常。但是它没有回滚,前2条记录被插入并提交。

然后我想到了快速尝试使用JPA EntityManager。

@PersistenceContext
private EntityManager em;

em.save(person);

然后我得到javax.persistence.TransactionRequiredException:没有可用的事务性EntityManager异常。

然后em.save(person)按预期工作,事务正常工作(意味着在RuntimeException发生时,它正在回滚所有的db插入)。

但是,即使使用Spring 4.0.5+Spring Data JPA1.6.0版本,当使用PersonRepository.save(person)而不是em.persist(person)时,事务也无法工作。

Spring Data JPA存储库似乎正在提交事务。

Maven pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sivalabs</groupId>
    <artifactId>springboot-data-jpa</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot-data-jpa</name>
    <description>Spring Boot Hello World</description>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.2.0.RELEASE</version>
        <relativePath />
    </parent>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <start-class>com.sivalabs.springboot.Application</start-class>
        <java.version>1.7</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <dependencies>
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
</project>

application.java

@EnableAutoConfiguration
@Configuration
@ComponentScan
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

共有1个答案

韩高峯
2023-03-14

来自@M-Deinum的评论:

使您的PersonServicepublic以及您正在调用的方法。

这似乎对几个用户起到了作用。同样的事情也涵盖在这个答案中,引用手册说:

 类似资料:
  • 我正试图在按下某个按钮时弹出一个警报对话框。我首先使用了Android Developer的示例代码而不是'这不起作用,所以我根据在这个站点上发现的情况进行了更改,但是现在我的程序在按下按钮后被迫停止。 就你的知识而言,这是在第二个不同于主要的活动中完成的。不确定这是否重要.... ‘ 碰撞日志:“03-25 19:34:24.373:E/AndroidRuntime(18828):致命异常:ma

  • 2,错误{org.apache.directory.server.LDAP.ldapserver}-ERR_171无法将LDAP服务(10,389)绑定到服务注册表。java.net.BindException:已在使用的地址 请帮忙谢谢 --------提示------------------- JAVA_HOME环境变量设置为/opt/java CARBON_HOME环境变量设置为/mnt/1

  • 我正在做一个类似生存的游戏,我有两种类型的碰撞,一种是玩家的敌人,另一种是敌人身上的子弹。我也有一个健康栏,由于某些原因,在picbox被移除后,健康仍然下降,就像敌人与玩家互动一样。 这是子弹碰撞代码的一个块(所有8个方向的所有代码都是相同的) 这是敌方与玩家碰撞的暗号

  • null 获取http://localhost:8888/image-service/default: 获取http://localhost:8888/image-service/prod 我在REST应用程序中激活了配置文件,但始终显示默认配置文件中的值。

  • 一般:我是一个想在Storm/Kafka/Flink/MS Azure SA/Spark上运行一些性能测试(WordCount)的学生。我想使用Kafka经纪人作为输入源。 我使用了Storm-Starter项目中的WordCount示例,并添加了Kafka作为喷口: 我使用kafka-console-producer生成一些消息。我希望有人能帮助我。我是编程Storm的新手...

  • 我正在尝试使用Hibernate验证器制作简单的验证表单。我的Customer类中有两个字段,我希望其中一个字段是必需的(lastName)。关键是,即使im没有填充这个字段,我也不会得到错误消息,BindingResult也不包含任何错误。我的代码中缺少什么吗? 编辑:表单代码: 编辑2:我添加到类路径validation-api.jar(包含抽象API和注释扫描程序)。 还插入了@initbi