Java Spring@transactional&x27;行不通

Java Spring@transactional&x27;行不通,java,spring,spring-mvc,spring-transactions,Java,Spring,Spring Mvc,Spring Transactions,我使用的是java配置,除了@transactional之外,其他一切都可以正常工作,我花了几天的时间试图弄清楚,但不知道为什么它不工作,如果有任何帮助,我将不胜感激 在UserController.java中,我尝试调用userService.testTransactional(用户,请求) testTransaction()是UserServiceImpl中的测试方法,“Long.valueOf(“Throw RuntimeException”);是在这个方法中要抛出异常的行,但是用户被添加

我使用的是java配置,除了@transactional之外,其他一切都可以正常工作,我花了几天的时间试图弄清楚,但不知道为什么它不工作,如果有任何帮助,我将不胜感激

在UserController.java中,我尝试调用userService.testTransactional(用户,请求)

testTransaction()是UserServiceImpl中的测试方法,“Long.valueOf(“Throw RuntimeException”);是在这个方法中要抛出异常的行,但是用户被添加了,它应该回滚,但是用户记录仍然存在

UserController.java

@Controller
public class UserController {

    @Resource(name="userService")
    protected UserService userService;

    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public String processRegister(Model model, @ModelAttribute RegisterForm registerForm, HttpServletRequest request) throws Exception {

        userService.testTransactional(user, request);

        return "account/register_success";
    }
}
UserServiceImpl.java

@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource
    private UserDao userDao;

    @Transactional
    public void testTransaction(User user, HttpServletRequest request) throws Exception {
        long userId = userDao.add(user);
        Long.valueOf("Throw RuntimeException");
    }
}
以下是我的配置

web.xml

<!-- Java-based annotation-driven Spring container definition -->
<context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>

<!-- Location of Java @Configuration classes that configure the components that makeup this application -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>com.myapp.config</param-value>
</context-param>


<!-- Secures the application -->
<filter>
    <filter-name>shiroFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>shiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher> 
</filter-mapping>

<!-- Handles requests into the application -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <!-- No explicit configuration file reference here: everything is configured in the root container for simplicity -->       
        <param-name>contextConfigLocation</param-name>
        <param-value></param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
DataConfig.java

@Configuration  // Specifies the class as configuration
@EnableWebMvc //Enables to use Spring's annotations in the code
@ComponentScan(basePackages = {"com.myapp.account"}) // Specifies which package to scan
public class AppConfig {
    ...
@Configuration
@EnableTransactionManagement
public class DataConfig {

    @Bean(destroyMethod="close")
    public ComboPooledDataSource dataSource() throws PropertyVetoException {
        ...
        return cpds;
    }

    @Bean
    public NamedParameterJdbcTemplate jdbcTemplate() throws PropertyVetoException {
        return new NamedParameterJdbcTemplate(dataSource());
    }

    @Bean
    public DataSourceTransactionManager transactionManager() throws PropertyVetoException {
        DataSourceTransactionManager dstm = new DataSourceTransactionManager(dataSource());
        return dstm;
    }


    @Bean
    public UserDao userDao() throws PropertyVetoException {
        return new UserDao(jdbcTemplate());
    }

问题是您没有在
@Configuration
类上指定
@EnableTransactionManagement
,该类正在扫描组件并创建
userserviceinpl
bean。假设该类位于
com.myapp.account
中,那么组件扫描它的配置类应该具有
@EnableTransactionManagement
。适当地更改您的
DataConfig
AppConfig

这是如何编译的?类userServiceImpl看起来应该扩展add(user)方法,或者至少类中应该存在add()方法。到底发生了什么?在代码的哪一行?让我猜猜,您还有一个
DispatcherServlet
,它(也)加载
AppConfig
类。这将导致bean重复,其中一个有事务,另一个没有事务,并且由于没有事务的bean更接近
控制器
,因此将使用它。更新了我的问题,它是部分代码,不可编译,testTransaction()是UserServiceImpl中的测试方法。java@zizibj-你还没说出什么问题。有例外吗?我在DataConfig.java上指定了@EnableTransactionManagement。@zizibj是的,但是
DataConfig
没有创建您的
UserServiceImpl
bean,因此它无法添加该行为。在我的问题中添加一些代码,很抱歉我的英语不好,我在DataConfig.java中创建了UserDAOBean,@Resource userService在my UserContrller中。@zizibj通过
userserviceinpl
上的
@Service
注释,如果您对该包使用
@ComponentScan
,Spring将创建该类的bean。但是,您的
@ComponentScan
在类
AppConfig
中,它没有
@EnableTransactionManagement
。感谢您的快速回复,只是尝试将@EnableTransactionManagement移动到AppConfig,它也不起作用。