You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring事务启用异常求助:javax.persistence.TransactionRequiredException

Hey there, let's figure out why your Spring MVC transactions aren't kicking in. From the partial config you shared, here are the most common culprits and actionable fixes to try:

1. You're missing transaction annotation-driven configuration

This is the #1 reason transactions fail to activate. Spring needs explicit instruction to recognize @Transactional annotations.

First, make sure your XML config includes the tx namespace, then add the annotation-driven tag:

<!-- Add these to your root beans element -->
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
    ...
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd"

<!-- Then enable annotation-driven transactions -->
<tx:annotation-driven transaction-manager="transactionManager"/>

2. No transaction manager bean is defined

You've set up the LocalContainerEntityManagerFactoryBean, but Spring needs a transaction manager to coordinate transactions with it. Add a JpaTransactionManager bean:

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="ecareEMF"/>
</bean>

3. Issues with @Transactional usage

Double-check these common mistakes:

  • You applied @Transactional to a private method: Spring AOP doesn't proxy private methods, so the annotation will be ignored. Move the annotation to a public method, or use AspectJ weaving if you need private method transactions.
  • The class with @Transactional isn't a Spring-managed bean: Make sure the class is annotated with @Service, @Component, or another stereotype annotation, and that it's within the ru.tsystems package scanned by <context:component-scan>.
  • You're catching exceptions without rethrowing them: If you catch a checked exception (like SQLException) and don't rethrow it, Spring won't trigger a rollback. Use @Transactional(rollbackFor = Exception.class) to force rollback on all exceptions, or rethrow the exception.

4. Full config example (filling in gaps)

Here's how your complete config should look to ensure transactions work:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/tx
           http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="ru.tsystems"/>

    <!-- Example data source config with HikariCP -->
    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ecare_db"/>
        <property name="username" value="your_db_username"/>
        <property name="password" value="your_db_password"/>
    </bean>

    <bean id="ecareEMF" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="ru.tsystems.persistence.entity"/>
        <!-- Add JPA vendor adapter (example for Hibernate) -->
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true"/>
                <property name="generateDdl" value="true"/>
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL8Dialect"/>
            </bean>
        </property>
    </bean>

    <!-- JPA Transaction Manager -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="ecareEMF"/>
    </bean>

    <!-- Enable annotation-driven transactions -->
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

5. Hidden gotcha: Internal method calls

If you're calling a @Transactional method from another method in the same class, Spring's proxy-based AOP won't trigger the transaction. For example:

@Service
public class UserService {
    public void updateUser() {
        this.doTransactionalUpdate(); // Transaction won't work here
    }

    @Transactional
    public void doTransactionalUpdate() {
        // DB operations
    }
}

Fix this by moving the transactional method to a separate Spring bean, or use AopContext.currentProxy() to call the method via the proxy.


内容的提问来源于stack exchange,提问作者Nikita Mikhailov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:17:58