`
jinnianshilongnian
  • 浏览: 21434341 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2405044
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2997694
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631469
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257571
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593160
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248971
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847542
Group-logo
跟我学Nginx+Lua开...
浏览量:698161
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780453
社区版块
存档分类
最新评论

Spring事务处理时自我调用的解决方案及一些实现方式的风险

阅读更多

 

前些日子一朋友在需要在目标对象中进行自我调用,且需要实施相应的事务定义,且网上的一种通过BeanPostProcessor的解决方案是存在问题的。因此专门写此篇帖子分析why。

1、预备知识

aop概念请参考【http://www.iteye.com/topic/1122401】和【http://jinnianshilongnian.iteye.com/blog/1418596

spring的事务管理,请参考【http://jinnianshilongnian.iteye.com/blog/1441271

 

 

使用AOP 代理后的方法调用执行流程,如图所示



也就是说我们首先调用的是AOP代理对象而不是目标对象,首先执行事务切面,事务切面内部通过TransactionInterceptor环绕增强进行事务的增强,即进入目标方法之前开启事务,退出目标方法时提交/回滚事务。

2、测试代码准备

public interface AService {
    public void a();
    public void b();
}
 
@Service()
public class AServiceImpl1 implements AService{
    @Transactional(propagation = Propagation.REQUIRED)
    public void a() {
        this.b();
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void b() {
    }
}

 

3、问题

目标对象内部的自我调用将无法实施切面中的增强,如图所示


 

此处的this指向目标对象,因此调用this.b()将不会执行b事务切面,即不会执行事务增强,因此b方法的事务定义“@Transactional(propagation = Propagation.REQUIRES_NEW)”将不会实施,即结果是ba方法的事务定义是一样的,可以从以下日志看出:

 

 org.springframework.transaction.annotation.AnnotationTransactionAttributeSource Adding transactional method 'a' with attribute: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''

org.springframework.beans.factory.support.DefaultListableBeanFactory Returning cached instance of singleton bean 'txManager'

org.springframework.orm.hibernate4.HibernateTransactionManager Creating new transaction with name [com.sishuok.service.impl.AServiceImpl1.a]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''  -----创建a方法事务

org.springframework.orm.hibernate4.HibernateTransactionManager Opened new Session …… for Hibernate transaction  ---打开Session

……

org.springframework.transaction.support.TransactionSynchronizationManager Initializing transaction synchronization

org.springframework.transaction.interceptor.TransactionInterceptor Getting transaction for [com.sishuok.service.impl.AServiceImpl1.a]

org.springframework.transaction.interceptor.TransactionInterceptor Completing transaction for [com.sishuok.service.impl.AServiceImpl1.a] ----完成a方法事务

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCommit synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCompletion synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Initiating transaction commit

 

org.springframework.orm.hibernate4.HibernateTransactionManager Committing Hibernate transaction on Session ……---提交a方法事务

org.springframework.orm.hibernate4.HibernateTransactionManager Rolling back Hibernate transaction on Session ……---如果有异常将回滚a方法事务

 

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCommit synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCompletion synchronization

org.springframework.transaction.support.TransactionSynchronizationManager Clearing transaction synchronization

……

org.springframework.orm.hibernate4.HibernateTransactionManager Closing Hibernate Session …… after transaction     --关闭Session

 

我们可以看到事务切面只对a方法进行了事务增强,没有对b方法进行增强。

 

3、解决方案

此处a方法中调用b方法时,只要通过AOP代理调用b方法即可走事务切面,即可以进行事务增强,如下所示:

public void a() {
aopProxy.b();//即调用AOP代理对象的b方法即可执行事务切面进行事务增强
}

 

判断一个Bean是否是AOP代理对象可以使用如下三种方法:

AopUtils.isAopProxy(bean)        : 是否是代理对象;

AopUtils.isCglibProxy(bean)       : 是否是CGLIB方式的代理对象;

AopUtils.isJdkDynamicProxy(bean) : 是否是JDK动态代理方式的代理对象;

3.1、通过ThreadLocal暴露Aop代理对象

1、开启暴露Aop代理到ThreadLocal支持(如下配置方式从spring3开始支持)

<aop:aspectj-autoproxy expose-proxy="true"/><!—注解风格支持-->
<aop:config expose-proxy="true"><!—xml风格支持--> 

   

2、修改我们的业务实现类

this.b();-----------修改为--------->((AService) AopContext.currentProxy()).b();

 

3、执行测试用例,日志如下

 

 

org.springframework.beans.factory.support.DefaultListableBeanFactory Returning cached instance of singleton bean 'txManager'

org.springframework.orm.hibernate4.HibernateTransactionManager Creating new transaction with name [com.sishuok.service.impl.AServiceImpl2.a]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''   -----创建a方法事务

org.springframework.orm.hibernate4.HibernateTransactionManager Opened new Session ……for Hibernate transaction  --打开a Session

org.springframework.orm.hibernate4.HibernateTransactionManager Preparing JDBC Connection of Hibernate Session ……

org.springframework.orm.hibernate4.HibernateTransactionManager Exposing Hibernate transaction as JDBC transaction ……

……

org.springframework.transaction.support.TransactionSynchronizationManager Initializing transaction synchronization

org.springframework.transaction.interceptor.TransactionInterceptor Getting transaction for [com.sishuok.service.impl.AServiceImpl2.a]

 

org.springframework.transaction.annotation.AnnotationTransactionAttributeSource Adding transactional method 'b' with attribute: PROPAGATION_REQUIRES_NEW,ISOLATION_DEFAULT; ''

……

org.springframework.orm.hibernate4.HibernateTransactionManager Suspending current transaction, creating new transaction with name [com.sishuok.service.impl.AServiceImpl2.b]  -----创建b方法事务(并暂停a方法事务)

……

org.springframework.orm.hibernate4.HibernateTransactionManager Opened new Session  for Hibernate transaction  ---打开b Session

……

org.springframework.transaction.support.TransactionSynchronizationManager Initializing transaction synchronization

org.springframework.transaction.interceptor.TransactionInterceptor Getting transaction for [com.sishuok.service.impl.AServiceImpl2.b]

org.springframework.transaction.interceptor.TransactionInterceptor Completing transaction for [com.sishuok.service.impl.AServiceImpl2.b] ----完成b方法事务

 

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCommit synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCompletion synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Initiating transaction commit

org.springframework.orm.hibernate4.HibernateTransactionManager Committing Hibernate transaction on Session …… ---提交b方法事务

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCommit synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCompletion synchronization

org.springframework.transaction.support.TransactionSynchronizationManager Clearing transaction synchronization

……

org.springframework.orm.hibernate4.HibernateTransactionManager Closing Hibernate Session …… after transaction  --关闭 b Session

 

-----到此b方法事务完毕

 

org.springframework.orm.hibernate4.HibernateTransactionManager Resuming suspended transaction after completion of inner transaction ---恢复a方法事务

……

org.springframework.transaction.support.TransactionSynchronizationManager Initializing transaction synchronization

org.springframework.transaction.interceptor.TransactionInterceptor Completing transaction for [com.sishuok.service.impl.AServiceImpl2.a] ----完成a方法事务

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCommit synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering beforeCompletion synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Initiating transaction commit

org.springframework.orm.hibernate4.HibernateTransactionManager Committing Hibernate transaction on Session ……---提交a方法事务

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCommit synchronization

org.springframework.orm.hibernate4.HibernateTransactionManager Triggering afterCompletion synchronization

org.springframework.transaction.support.TransactionSynchronizationManager Clearing transaction synchronization

……

org.springframework.orm.hibernate4.HibernateTransactionManager Closing Hibernate Session …… after transaction  --关闭 a Session

 

 

 

此处我们可以看到b方法的事务起作用了。

 

以上方式是解决目标对象内部方法自我调用并实施事务的最简单的解决方案。

 

4、实现原理分析

4.1、在进入代理对象之后通过AopContext.serCurrentProxy(proxy)暴露当前代理对象到ThreadLocal,并保存上次ThreadLocal绑定的代理对象为oldProxy

4.2、接下来我们可以通过 AopContext.currentProxy() 获取当前代理对象;

4.3、在退出代理对象之前要重新将ThreadLocal绑定的代理对象设置为上一次的代理对象,即AopContext.serCurrentProxy(oldProxy)

 

有些人不喜欢这种方式,说通过ThreadLocal暴露有性能问题,其实这个不需要考虑,因为事务相关的(SessionConnection)内部也是通过SessionHolderConnectionHolder暴露到ThreadLocal实现的。

 

不过自我调用这种场景确实只有很少情况遇到,因此不用这种方式我们也可以通过如下方式实现。

3.2、通过初始化方法在目标对象中注入代理对象

@Service
public class AServiceImpl3 implements AService{
    @Autowired  //①  注入上下文
    private ApplicationContext context;
    
    private AService proxySelf; //②  表示代理对象,不是目标对象
    @PostConstruct 	//③ 初始化方法
    private void setSelf() {
        //从上下文获取代理对象(如果通过proxtSelf=this是不对的,this是目标对象)
        //此种方法不适合于prototype Bean,因为每次getBean返回一个新的Bean
        proxySelf = context.getBean(AService.class); 
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void a() {
       proxySelf.b(); //④ 调用代理对象的方法 这样可以执行事务切面
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void b() {
    }
}

 

此处日志就不分析,和3.1类似。此种方式不是很灵活,所有需要自我调用的实现类必须重复实现代码。

3.3、通过BeanPostProcessor 在目标对象中注入代理对象

此种解决方案可以参考http://fyting.iteye.com/blog/109236

 

BeanPostProcessor 的介绍和使用敬请等待我的下一篇分析帖。

 

一、定义BeanPostProcessor 需要使用的标识接口

 

public interface BeanSelfAware {
    void setSelf(Object proxyBean);
}

 即我们自定义的BeanPostProcessor InjectBeanSelfProcessor)如果发现我们的Bean是实现了该标识接口就调用setSelf注入代理对象。

 

二、Bean实现

@Service
public class AServiceImpl4 implements AService, BeanSelfAware {//此处省略接口定义
    private AService proxySelf;
    public void setSelf(Object proxyBean) { //通过InjectBeanSelfProcessor注入自己(目标对象)的AOP代理对象
        this.proxySelf = (AService) proxyBean;
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void a() {
        proxySelf.b();//调用代理对象的方法 这样可以执行事务切面
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void b() {
    }
} 

实现BeanSelfAware标识接口的setSelf将代理对象注入,并且通过“proxySelf.b()”这样可以实施b方法的事务定义。

 

三、InjectBeanSelfProcessor实现

 

@Component
public class InjectBeanSelfProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(bean instanceof BeanSelfAware) {//如果Bean实现了BeanSelfAware标识接口,就将代理对象注入
            ((BeanSelfAware) bean).setSelf(bean); //即使是prototype Bean也可以使用此种方式
        }
        return bean;
    }
}

 

postProcessAfterInitialization根据目标对象是否实现BeanSelfAware标识接口,通过setSelf(bean)将代理对象(bean)注入到目标对象中,从而可以完成目标对象内部的自我调用。

 

关于BeanPostProcessor的执行流程等请一定参考我的这篇帖子,否则无法继续往下执行。

 

四、InjectBeanSelfProcessor的问题

1、场景:通过InjectBeanSelfProcessor进行注入代理对象且循环依赖场景下会产生前者无法通过setSelf设置代理对象的问题。 循环依赖是应该避免的,但是实际工作中不可避免会有人使用这种注入,毕竟没有强制性。

 

2、用例

2.1定义BeanPostProcessor 需要使用的标识接口

3.1中一样此处不再重复。

 

2.2Bean实现

 

@Service
public class AServiceImpl implements AService, BeanSelfAware {//此处省略Aservice接口定义
    @Autowired
    private BService bService;   //①  通过@Autowired方式注入BService
    private AService self;       //②  注入自己的AOP代理对象
    public void setSelf(Object proxyBean) {
        this.self = (AService) proxyBean;  //③ 通过InjectBeanSelfProcessor注入自己(目标对象)的AOP代理对象
        System.out.println("AService=="+ AopUtils.isAopProxy(this.self)); //如果输出true标识AOP代理对象注入成功
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void a() {
        self.b();
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void b() {
    }
}

  

 

@Service
public class BServiceImpl implements BService, BeanSelfAware {//此处省略Aservice接口定义
    @Autowired
    private AService aService;  //①  通过@Autowired方式注入AService
    private BService self;      //②  注入自己的AOP代理对象
    public void setSelf(Object proxyBean) {  //③ 通过InjectBeanSelfProcessor注入自己(目标对象)的AOP代理对象
        this.self = (BService) proxyBean;
        System.out.println("BService=" + AopUtils.isAopProxy(this.self)); //如果输出true标识AOP代理对象注入成功
    }
    @Transactional(propagation = Propagation.REQUIRED)
    public void a() {
        self.b();
    }
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void b() {
    }
}

此处A依赖BB依赖A,即构成循环依赖,此处不探讨循环依赖的设计问题(实际工作应该避免循环依赖),只探讨为什么循环依赖会出现注入代理对象失败的问题。

 

循环依赖请参考我的博文【http://jinnianshilongnian.iteye.com/blog/1415278】。

依赖的初始化和销毁顺序请参考我的博文【http://jinnianshilongnian.iteye.com/blog/1415461】。

 

2.3InjectBeanSelfProcessor实现

和之前3.3中一样 此处不再重复。

 

2.4、测试用例

 

@RunWith(value = SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = {"classpath:spring-config.xml"})
public class SelfInjectTest {
    @Autowired
    AService aService;
    @Autowired
    BService bService;
    @Test
    public void test() {
    }
}

  

执行如上测试用例会输出:

BService=true

AService==false

BService通过InjectBeanSelfProcessor注入代理对象成功,而AService却失败了(实际是注入了目标对象),如下是debug得到的信息:

 


 

 

2. 5、这是为什么呢,怎么在循环依赖会出现这种情况?

 

敬请期待我的下一篇分析帖。

3.4、改进版的InjectBeanSelfProcessor的解决方案

@Component
public class InjectBeanSelfProcessor2 implements BeanPostProcessor, ApplicationContextAware {
    private ApplicationContext context;
    //① 注入ApplicationContext
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(!(bean instanceof BeanSelfAware)) { //② 如果Bean没有实现BeanSelfAware标识接口 跳过
            return bean;
        }
        if(AopUtils.isAopProxy(bean)) { //③ 如果当前对象是AOP代理对象,直接注入
            ((BeanSelfAware) bean).setSelf(bean);
        } else {
            //④ 如果当前对象不是AOP代理,则通过context.getBean(beanName)获取代理对象并注入
            //此种方式不适合解决prototype Bean的代理对象注入
            ((BeanSelfAware)bean).setSelf(context.getBean(beanName));
        }
        return bean;
    }
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}

 

5、总结

纵观其上:

3.1 通过ThreadLocal暴露Aop代理对象】适合解决所有场景(不管是singleton Bean还是prototype Bean)的AOP代理获取问题(即能解决目标对象的自我调用问题);

 

3.2 通过初始化方法在目标对象中注入代理对象】 和【3.4 改进版的InjectBeanSelfProcessor的解决方案】能解决普通(无循环依赖)的AOP代理对象注入问题,而且也能解决【3.3】中提到的循环依赖(应该是singleton之间的循环依赖)造成的目标对象无法注入AOP代理对象问题,但该解决方案不适合解决循环依赖中包含prototype Bean的自我调用问题;

 

3.3 通过BeanPostProcessor 在目标对象中注入代理对象】:只能解决 普通(无循环依赖)的 Bean注入AOP代理无法解决循环依赖的AOP代理对象注入问题,即无法解决目标对象的自我调用问题。

 

没有完美的解决方案,只有最适用的解决方案。

 

测试代码请参考附件,jar包与http://www.iteye.com/topic/1120924使用的是一样的

29
5
分享到:
评论
7 楼 luodaxu 2016-07-28  
[color=ornge][/color]           
6 楼 skill7899 2016-06-24  
http://www.iteye.com/topic/494124 这里有一种更优雅的解决方案,可是我测了不可以。能帮忙看一下吗?! ,谢谢。
5 楼 xiayh04 2014-03-28  
点埰的,不需要给点理由嘛?这类人甚而tm心态!
4 楼 s233642864 2013-02-27  
学习了。1楼讲的发生原因也受启发
3 楼 islandoo 2013-02-26  
所以说啊,还是编程事务比声明事务要好用。没有这么多麻烦。
2 楼 6Glory9 2012-09-04  
居然被我找到答案了。哈哈。谢谢
1 楼 Technoboy 2012-07-12  
之所以出现这个问题,是因为:我们使用aop进行代理,当执行proxy类的a方法时,会进行拦截(开启事物),紧接着逻辑走到target类上a方法,而后调用target类的b方法。此时需要明白,它调用的是target类上的b方法,而不是proxy类的b方法。要知道,针对方法b的横切逻辑,只植入到了proxy类上的方法b中。所以target类的a方法中所调用的b方法没有开启事物。

相关推荐

    spring杂谈 作者zhang KaiTao

    1.1 Spring事务处理时自我调用的解决方案及一些实现方式的风险 1.2 我对AOP的理解 1.3 Spring开闭原则的表现-BeanPostProcessor的扩展点-1 1.4 我对IoC/DI的理解 1.5 SpringMVC + spring3.1.1 + hibernate4.1.0 集成...

    Spring攻略(第二版 中文高清版).part1

    1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用构造程序创建Bean 14 1.3.1 问题 14 1.3.2 解决方案 14 1.3.3 ...

    Spring攻略(第二版 中文高清版).part2

    1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用构造程序创建Bean 14 1.3.1 问题 14 1.3.2 解决方案 14 1.3.3 ...

    基于Spring Boot 2+Spring Cloud+vue开发的支持一致性分布式事务、服务异常定位方案的底层开发框架

    基于Spring Boot 2和Spring Cloud Finchley.SR2,更符合企业级的分布式和服务化解决方案,Roses拥有高效率的开发体验,提供可靠消息最终一致性分布式事务解决方案,提供基于调用链的服务治理,提供可靠的服务异常...

    基于Spring Boot 2和Spring Cloud Finchley.RELEASE,致力做更简洁的分布式和服务化解决方案

    本项目为Roses系列微服务框架的模块之一,Roses基于Spring Boot 2和Spring Cloud Finchley.RELEASE,致力做更简洁的分布式和服务化解决方案,Roses拥有高效率的开发体验,提供可靠消息最终一致性分布式事务解决方案...

    Spring2.52 开发手册

    Spring为编写企业应用程序提供了轻量的解决方案,同时仍然支持使用声明式事务、 用RMI或web service远程调用、以及使用多种方式来将数据持久化到数据库。Spring提供了全功能的 MVC framework, 以及透明集成AOP到你...

    分布式系统事务一致性解决方案大对比,谁最好使?

    分布式系统的事务一致性是一个技术难题,各种解决方案孰优孰劣? 在OLTP系统领域,我们在很多业务场景下都会面临事务一致性方面的需求,例如最经典的Bob给Smith转账的案例。传统的企业开发,系统往往是以单体应用...

    Spring 2.0 开发参考手册

    9.9. 公共问题的解决方案 9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1....

    Spring-Reference_zh_CN(Spring中文参考手册)

    9.9. 公共问题的解决方案 9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 ...

    Spring中文帮助文档

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知...

    Spring.3.x企业应用开发实战(完整版).part2

    10.3.1 Spring事务传播机制回顾 10.3.2 相互嵌套的服务方法 10.4 多线程的困惑 10.4.1 Spring通过单实例化Bean简化多线程问题 10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的...

    Spring API

    9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知...

    spring chm文档

    9.9. 公共问题的解决方案 9.9.1. 对一个特定的 DataSource 使用错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1....

    SpringBoot内部调用事务不起作用问题的解决方案

    主要介绍了SpringBoot事务不起作用问题的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    fat:基于springboot,zookeeper,redis分布式事务强一致性方案

    脂肪FAT,基于springboot,使用zookeeper,redis,spring异步,spring transactionManager的强一致性分布式事务解决方案框架介绍纯编码方式,强一致性。使用redis / zookeeper作为注册中心,代理事务的执行,使用...

    Spring3.x企业应用开发实战(完整版) part1

    10.3.1 Spring事务传播机制回顾 10.3.2 相互嵌套的服务方法 10.4 多线程的困惑 10.4.1 Spring通过单实例化Bean简化多线程问题 10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的...

    Spring Framework 开发参考手册

    Spring为编写企业应用程序提供了轻量的解决方案,同时仍然支持使用声明式事务、 用RMI或web service远程调用、以及使用多种方式来将数据持久化到数据库。Spring提供了全功能的 MVC framework, 以及透明集成AOP到你...

    Spring-Reference_zh_CN

    Spring为编写企业应用程序提供了轻量的解决方案,同时仍然支持使用声明式事务、 用RMI或web service远程调用、以及使用多种方式来将数据持久化到数据库。Spring提供了全功能的 MVC framework, 以及透明集成AOP到你...

    Spring2.5中文版.zip

    Spring为编写企业应用程序提供了轻量的解决方案,同时仍然支持使用声明式事务、 用RMI或web service远程调用、以及使用多种方式来将数据持久化到数据库。Spring提供了全功能的 MVC framework, 以及透明集成AOP到你...

Global site tag (gtag.js) - Google Analytics