Spring Managed Transaction提交不应在的位置 [英] Spring managed Transaction commits where it shouldn't

查看:75
本文介绍了Spring Managed Transaction提交不应在的位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在"applicationContext-base.xml"中,我在下面添加:

in "applicationContext-base.xml" I add below:

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

     .....

    <!-- transaction support-->
    <!-- PlatformTransactionMnager -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- enable transaction annotation support -->
    <tx:annotation-driven transaction-manager="txManager" />

并且我想为控制器"中的功能设置事务

and I want to setup a transaction to a function in the "controller"

@Controller
@RequestMapping("/ywdata")
public class YwController  extends BaseController{
....
@Transactional(timeout=1)
private void submitNewSXSQ(Map map, HttpServletRequest request, HttpServletResponse response) throws Exception {

    ...//STEP1 :do some db insert and update STEP1
    if(true)
        throw new Exception("test transaction ");

     ...//STEP2: do another db insert and update

,我希望永远不要提交db操作,因为我在返回之前抛出了异常.但实际上不是.

and I expected the db operation should never be commit since I throw a exception before return. but actually not.

推荐答案

您的代码存在多个问题:

There are multiple issues with your code:

  • @Transactional on private methods don't work
  • @Transactional on @Controller annotated classes usually don't work
  • rollback is not performed for checked exceptions

最后一个问题很容易理解.让我解释一下前两个问题. Spring中的AOP是这样的:

The last issue can be easily understood. Let me explain the first two problems. AOP in Spring works like this:

  • 在初始化应用程序上下文之前,Spring搜索需要方法拦截的bean
  • 为每个这些bean注册一个特殊的代理bean ...该代理是目标bean的动态接口实现(JDK代理)或动态子类(CGLIB代理)
  • 代理替换了您的bean的定义...原始定义已重命名并标记为不适合自动装配(但仍存在于应用程序上下文中)
  • 代理上的方法非常笨拙-它们所做的只是拦截逻辑(即在执行之前/之后/周围调用某些方面)并调用原始的代理目标bean方法

为什么私有方法有问题:

Why private methods are problem:

  • 使用JDK代理(默认):
      如果您在非接口方法上使用@Transactional(仅代理中存在接口方法),则
    • @Transactional将不起作用
    • with JDK proxying (default):
      • @Transactional won't work if you have @Transactional on non-interface method (only interface methods are present on the proxy)
        如果您在私有或最终方法上使用@Transactional
      • @@Transactional将不起作用(动态子类中只能覆盖非私有和非最终方法)
      • @@Transactional won't work if you have @Transactional on private or final method (only non-private and non-final methods can be overridden in dynamic subclass)

      以及控制器有问题的原因:

      And why controllers are problem:

      • Spring的RequestMappingHandlerMapping(负责将请求映射到您的@Controllers的bean)要求应用程序上下文获取所有带有@Controller批注的bean
        • 这可能会返回您的原始类,而不是代理(我认为Spring JIRA中存在此错误,因此可能已修复)
        • 如果使用JDK代理,则需要将注释添加到接口(以便对代理进行注释)...这意味着您需要为控制器定义接口
        • Spring's RequestMappingHandlerMapping (bean responsible for mapping requests to your @Controllers) asks application context to get all beans with @Controller annotation
          • this might return your original class, not the proxy (I think there was a bug for this in Spring JIRA, so it might be already fixed)
          • in case of JDK proxying, you need to add the annotation to the interface (so that the proxy is annotated)... this means that you would need to define interfaces for your controllers

          做什么:

          • 我建议您将事务处理移至服务级别
          • 如果您希望将事务封装在整个请求中,则可以从 TransactionTemplate 助手类.

          这篇关于Spring Managed Transaction提交不应在的位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆