Java 如何使用@Transactional在spring中实现真正的事务

Java 如何使用@Transactional在spring中实现真正的事务,java,spring,spring-boot,transactions,Java,Spring,Spring Boot,Transactions,我有2个存储库-每个存储库都有不同对象的保存方法。 我想将这两个方法作为事务执行,这意味着如果其中一个失败,事务将回滚。(我认为这就是交易的含义) 这是我的密码: @Repository public class BananaRep { private JdbcTemplate jdbc; @Autowired public BananaRep(JdbcTemplate jdbc) { this.jdbc = jdbc; } publ

我有2个存储库-每个存储库都有不同对象的保存方法。 我想将这两个方法作为事务执行,这意味着如果其中一个失败,事务将回滚。(我认为这就是交易的含义)

这是我的密码:

@Repository
public class BananaRep {

    private JdbcTemplate jdbc;

    @Autowired
    public BananaRep(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    public void saveBanana(Banana banana) {
        jdbc.update("insert into ......", ...);
    }
}

@Repository
public class TomatoRep {
    private JdbcTemplate jdbc;

    @Autowired
    public TomatoRep(JdbcTemplate jdbc) {
        this.jdbc = jdbc;
    }

    public void saveTomato(Tomato tomato) {
        jdbc.update("insert into ... ", ....);
    }
}

@RestController
public class MixController {
    @Autowired
    BananaRep bananaRep;
    @Autowired
    TomatoRep tomatoRep;

    @Transactional
    @RequestMapping(value="/mix", method= RequestMethod.GET)
    public Car mix() {

        Banana banana = new Banana(....);
        bananaRep.saveBanana(banana );

        Tomato tomato= new Tomato(...);
        tomatoRep.saveTomato(tomato);
        return banana;
    }
}
我的身材:

buildscript {
    ext {
        springBootVersion = '2.0.0.M2'
    }
    repositories {
        mavenCentral()
        maven { url "https://repo.spring.io/snapshot" }
        maven { url "https://repo.spring.io/milestone" }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
    maven { url "https://repo.spring.io/snapshot" }
    maven { url "https://repo.spring.io/milestone" }
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-jersey')
    compile('org.springframework.boot:spring-boot-starter-web')
    compile('org.springframework.boot:spring-boot-starter-jdbc')
    compile('mysql:mysql-connector-java')
}
为了测试它,我更改了Tomato表中一个db列的名称,因此在我的控制器中,saveTomato(Tomato)方法将失败。如果发生这种情况,我想把香蕉卷回去。我认为@Transactional方法注释应该是这样的,但我错了

那么如何实现我的目标呢

@Autowired
    private SessionFactory sessionFactory;

@Transactional
    @RequestMapping(value="/mix", method= RequestMethod.GET)
    public Car mix() {
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        Banana banana = new Banana(....);
        bananaRep.saveBanana(banana );

        Tomato tomato= new Tomato(...);
        tomatoRep.saveTomato(tomato);
        session.getTransaction().commit();
        return banana;
    }
对于bean:

import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean;

 @Bean
    public HibernateJpaSessionFactoryBean sessionFactory(){
        return new HibernateJpaSessionFactoryBean();
    } 
我不知道这是否是最好的解决方案,但在我的情况下,这是可行的;)

对于bean:

import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean;

 @Bean
    public HibernateJpaSessionFactoryBean sessionFactory(){
        return new HibernateJpaSessionFactoryBean();
    } 


我不知道这是否是最好的解决方案,但在我的情况下,这是可行的;)

事务控制应该放在服务业务处理层

事务控制应该放在服务业务处理层

问题是我在MySQL表中使用了MyISAM,它们不支持事务。这对我来说是个大问题。我希望我的解决方案能帮助像我这样的人。

问题是我在MySQL表中使用了MyISAM,他们不支持事务。这对我来说是个大问题。我希望我的解决方案能帮助像我这样的人。

您没有使用spring boot,是吗?如果没有,您是否声明了
数据源TransactionManager
?请显示配置。请维护会话工厂和事务对象。是否使用
@EnableAutoConfiguration
创建数据源?您应该有一个由Spring自动创建的
DataSourceTransactionManager
bean。我没有@EnableAutoConfiguration,也不需要它。它的弹簧靴。但事实上,我不能用两个查询进行交易。如果spring框架不能实现这一点,那就太傻了#你不是在用弹簧靴吧?如果没有,您是否声明了
数据源TransactionManager
?请显示配置。请维护会话工厂和事务对象。是否使用
@EnableAutoConfiguration
创建数据源?您应该有一个由Spring自动创建的
DataSourceTransactionManager
bean。我没有@EnableAutoConfiguration,也不需要它。它的弹簧靴。但事实上,我不能用两个查询进行交易。如果spring框架不能实现这一点,那就太傻了#艾尔弗:我看不出结构。这只是一个例子,不要看结构。这只是一个例子。为了获得SessionFactory,我应该向spring boot添加什么依赖项?我认为这个依赖项:spring boot starter数据JPA以及如何配置bean,因为它说找不到SessionFactory类型的bean?还有@Transactional传播之类的方法吗?这个注释是无用的。当我设置这个配置时,另一个类就失败了:考虑在你的配置中定义一个名为“EntIdMauleCurror”的bean。看看你的服务不应该是一个没有注意事项的事务和你的应用程序是否允许事务管理……通常,事务性注释执行提交。在我的例子中,我使用sessionFactory是因为我遇到了同样的问题,时间也不多。为了获得sessionFactory,我应该向spring boot添加什么依赖项?我认为这个依赖项:spring boot starter数据JPA以及如何配置bean,因为它说找不到sessionFactory类型的bean?还有@Transactional传播之类的方法吗?这个注释是无用的。当我设置这个配置时,另一个类就失败了:考虑在你的配置中定义一个名为“EntIdMauleCurror”的bean。看看你的服务不应该是一个没有注意事项的事务和你的应用程序是否允许事务管理……通常,事务性注释执行提交。在我的例子中,我使用sessionFactory是因为我有同样的问题,而且时间很少。