@Transactional在我的Spring Boot应用程序中没有任何作用

时间:2018-10-03 14:31:36

标签: java hibernate spring-boot transactions spring-data-jpa

这是一个令人困惑的问题。我已经阅读了数十个旨在解释如何使用@Transactional的链接,但我已确认没有任何事务正在创建。

Main.java

@SpringBootApplication
@EnableJpaRepositories(basePackages="com.mypackage")
@EnableTransactionManagement
@EntityScan(basePackages=["com.mypackage"])
@EnableJpaAuditing
public class Main {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }
}

SubscriptionController.java

@RequestMapping("/api/subscription")
@RestController
public class SubscriptionController {
    @Autowired SubscriptionService subscriptionService;
    Logger log = LogManager.getLogger(this.getClass().getName());
    public Collection<Subscriptions> subscribe(...) {
        log.info("transName: " + TransactionSynchronizationManager.getCurrentTransactionName + ", isAlive: " + TransactionSynchronizationManager.isActualTransactionActive());
        return subscriptionService.getAllSubscriptions();
    }
} 

SubscriptionService.java

@Service
public class SubscriptionService {
    @Transactional public Collection<Subscription> getAllSubscriptions() {
        log.info("transName: " + TransactionSynchronizationManager.getCurrentTransactionName() + ", isAlive: " + TransactionSynchronizationManager.isActualTransactionActive());
        //return subscriptions via JPQL queries here
    }
}

build.gradle

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:2.0.0.RELEASE")
    }
}

plugins {
    id 'war'
}

apply plugin: 'org.springframework.boot'

repositories {
    mavenCentral()
}

def springVersion = '5.0.3.RELEASE'
dependencies {
    compile 'org.codehaus.groovy:groovy-all:2.3.11'
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile "org.springframework.security:spring-security-core:${springVersion}", exclude
    compile "org.springframework.security:spring-security-config:${springVersion}", exclude
    compile "org.springframework.security:spring-security-web:${springVersion}", exclude
    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile "org.springframework:spring-test:${springVersion}", exclude
    implementation 'org.springframework.boot:spring-boot-starter-web:2.0.5.RELEASE', exclude
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.0.5.RELEASE'
    compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.11'
    compile 'org.liquibase:liquibase-core:3.6.1'
    compile 'org.liquibase:liquibase-groovy-dsl:1.2.2'
}

因此,当我运行api调用时,日志输出为null和false。 @Transactional的合同说,事务方面的代码将被编织到带注释的事务方法中,这样在该方法之前将建立一个事务(并因此建立一个实体管理器和数据库连接),并在此之后的某个时间关闭。但这是无关紧要的,因为在控制器运行之前不应该立即创建一个entitymanager吗?这两件事在这里都不起作用。 spring和@Transactional都没有设置任何事务。除了通过JpaRepository的子类可以执行的操作之外,这将导致无法执行任何类型的查询。我的Jpa存储库以某种方式能够为自己的方法设置事务。但是,如果他们的结果具有延迟初始化的属性怎么办?我需要一个休眠会话来获取这些。所以我需要交易。

4 个答案:

答案 0 :(得分:1)

您要为@Transactional使用什么课程?
您应该使用org.springframework.transaction.annotation.Transactional

答案 1 :(得分:0)

尝试删除

@EnableJpaRepositories(basePackages="com.mypackage")
@EnableTransactionManagement

SpringBoot应该自动执行这些操作

答案 2 :(得分:0)

使用spring初始值设定项(https://start.spring.io/)的现成的Spring-boot应用程序将正确处理事务。如果使自己成为具有单元测试的沙箱,则可以观察到示例中完成的事务划分将产生事务。这是我的git hub示例:https://github.com/skjenco/hibernateSandbox.git

代码:

@Test
@Transactional
public void test() {

    logger.info(TransactionSynchronizationManager.getCurrentTransactionName());
    .....

为使事务划分工作正常进行,您必须位于一个由Spring管理的对象(组件,服务,托管Bean等)中。在上述情况下,您似乎在Spring托管服务中。使用有效的沙箱可能有助于解决问题,这是我为解决复杂的休眠问题所做的工作。

答案 3 :(得分:0)

您可能还想发布pom.xml文件。应该添加spring-dataspring-tx依赖性,以便自动配置器创建事务管理器。否则,显式创建一个事务管理器bean,然后再次运行代码。

您可以为TRACE启用org.springframework级日志,并查看事务管理器是否已初始化。 还要检查事务拦截器日志。使用logging.level.org.springframework.transaction.interceptor=TRACE