多数据源 spring怎么管理事务的
发布网友
发布时间:2022-04-23 14:36
我来回答
共1个回答
热心网友
时间:2022-04-08 12:52
在SpringSide 3 中,白衣提供的预先配置好的环境非常有利于用户进行快速开发,但是同时也会为扩展带来一些困难。最直接的例子就是关于在项目中使用多个数据源的问题,似乎 很难搞。在上一篇中,我探讨了SpringSide 3 中的数据访问层,在这一篇中,我立志要解决多数据源配置的难题,我的思路是这样的:
第一步、测试能否配置多个DataSource
第二步、测试能否配置多个SessionFactory
第三步、测试能否配置多个TransactionManager
第四步、测试能否使用多个TransactionManager,也就是看能否配置多个
基本上到第四步就应该走不通了,因为Spring中似乎不能配置多个,而且@transactional注解也无法让用户选择具体使用哪个TransactionManager。也就是说,在SpringSide的应用中,不能让不同的数据源分别属于不同的事务管理器,多数据源只能使用分布式事务管理器,那么测试思路继续如下进行:
第五步、测试能否配置JTATransactionManager
如果到这一步,项目还能顺利在Tomcat中运行的话,我们就算大功告成了。但我总认为事情不会那么顺利,我总觉得JTATransactionManager需要应用服务器的支持,而且需要和JNDI配合使用,具体是不是这样,那只有等测试后才知道。如果被我不幸言中,那么进行下一步:
第六步、更换Tomcat为GlassFish,更换JDBC的DataSource为JNDI查找的DataSource,然后配置JTATransactionManager
下面测试开始,先假设场景,还是继续用上一篇中提到的简单的文章发布系统,假设该系统运行一段时间后非常火爆,单靠一台服务器已经无法支持巨大的用户数, 这时候,站长想到了把数据进行水平划分,于是,需要建立一个索引数据库,该索引数据库需保存每一篇文章的Subject及其内容所在的Web服务器,而每 一个Web服务器上运行的项目,需要同时访问索引数据库和内容数据库。所以,需要创建索引数据库,如下:
[java] view plain copy
create database puretext_index;
use puretext_index;
create table articles(
id int primary key auto_increment,
subject varchar(256),
webserver varchar(30)
);
第一步测试,配置多个DataSource,配置文件如下:
application.properties:
[java] view plain copy
jdbc.urlContent=jdbc:mysql://localhost:3306/PureText useUnicode=true&characterEncoding=utf8
jdbc.urlIndex=jdbc:mysql://localhost:3306/PureText_Index useUnicode=true&characterEncoding=utf8
applicationContext.xml:
[java] view plain copy
< xml version="1.0" encoding="UTF-8" >
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" default-lazy-init="true" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<description>Spring公共配置文件 </description>
<!-- 定义受环境影响易变的变量 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE">
<property name="ignoreResourceNotFound" value="true">
<property name="locations">
<list>
<!-- 标准配置 -->
<value>classpath*:/application.properties</value>
<!-- 本地开发环境配置 -->
<value>classpath*:/application.local.properties</value>
<!-- 服务器生产环境配置 -->
<!---->file:/var/myapp/application.server.properties -->
<!--!----></list>
</property>
</property></property></bean>
<!-- 使用annotation 自动注册bean,并保证@Required,@Autowired的属性被注入 -->
<context:component-scan base-package="cn.puretext">
<!-- 数据源配置,使用应用内的DBCP数据库连接池 -->
<bean id="dataSourceContent" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- Connection Info -->
<property name="driverClassName" value="com.mysql.jdbc.Driver">
<property name="url" value="${jdbc.urlContent}">
<property name="username" value="${jdbc.username}">
<property name="password" value="${jdbc.password}">
<!-- Connection Pooling Info -->
<property name="initialSize" value="5">
<property name="maxActive" value="100">
<property name="maxIdle" value="30">
<property name="maxWait" value="1000">
<property name="poolPreparedStatements" value="true">
<property name="defaultAutoCommit" value="false">
</property></property></property></property></property></property></property></property></property></property></bean>
<bean id="dataSourceIndex" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- Connection Info -->
<property name="driverClassName" value="com.mysql.jdbc.Driver">
<property name="url" value="${jdbc.urlIndex}">
<property name="username" value="${jdbc.username}">
<property name="password" value="${jdbc.password}">
<!-- Connection Pooling Info -->
<property name="initialSize" value="5">
<property name="maxActive" value="100">
<property name="maxIdle" value="30">
<property name="maxWait" value="1000">
<property name="poolPreparedStatements" value="true">
<property name="defaultAutoCommit" value="false">
</property></property></property></property></property></property></property></property></property></property></bean>
<!-- 数据源配置,使用应用服务器的数据库连接池 -->
<!--<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/ExampleDB">-->
<!-- Hibernate配置 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSourceContent">
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy">
</bean></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider
</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">${hibernate.ehcache_config_file}</prop>
</props>
</property>
<property name="packagesToScan" value="cn.puretext.entity.*">
</property></property></bean>
<!-- 事务管理器配置,单数据源事务 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory">
</property></bean>
<!-- 事务管理器配置,多数据源JTA事务-->
<!-- id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager or
WebLogicJtaTransactionManager">
-->
<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager">
</tx:annotation-driven><!--!----><!--!--<jee:jndi-lookup--></context:component-scan></beans>
Spring中事务管理的两种方式?
spring的事务管理有几种方式实现,如何实现Spring提供了许多内置事务管理器实现,常用的有以下几种:DataSourceTransactionManager(JDBC局部事务),HibernateTransactionManager(Hibernate事务),和JtaTransactionManager(JTA全局事务)。传统使用JDBC的事务管理以往使用JDBC进行数据操作,使用DataSource,从数据源中得...
多数据源 spring怎么管理事务的
第四步、测试能否使用多个TransactionManager,也就是看能否配置多个 基本上到第四步就应该走不通了,因为Spring中似乎不能配置多个,而且@transactional注解也无法让用户选择具体使用哪个TransactionManager。也就是说,在SpringSide的应用中,不能让不同的数据源分别属于不同的事务管理器,多数据源只能使用分布...
spring 两个数据源 怎么配事务
使用JTA事务,jboss,weblogic,websphere 等等ejb容器都自带了jta事务的支持,如果你使用tomcat,jetty或者其他web容器,则需要安装第三方的jta插件,假定这里使用jboss容器,则需要在jboss中配置JNDI数据源,比如有两个mysql的数据源需要被JTA管理,则需要在jboss的server/default/deploy目录下新建两个数据源文件a...
spring的事务管理有几种方式实现,如何实现
读数据不需要或只为其指定只读事务,而数据的插入,修改,删除就需要事务管理了。一种常见的事务管理配置:事务拦截器TransactionInterceptor和事务自动代理BeanNameAutoProxyCreator相结合的方式<!--定义Hibernate的事务管理器HibernateTransactionManager --> <bean id="transactionManager" class="org.springframework.orm.hibe...
springboot多事物管理器能在一个方法执行吗
在SpringBoot中,多数据源的事务管理器不能在一个方法执行中同时使用的原因与Spring框架的事务机制有关,Spring框架通过注解或XML配置来定义事务的边界和属性,当涉及到多数据源时,在一个方法中使用多个数据源,其事务管理器是不同的,而且不同数据源的事务管理器可能对应不同的数据库连接,Spring无法确保...
Spring Boot 项目中配置多数据源@Transactional注解失效问题
当一个Spring Boot 项目在配置了多个数据源 , 在编写 Service层方法 的时候 , 直接在service方法的上添加的 @Transactional 直接实现事务管理的方式是失效的 .以最近接触到的一个持久层框架使用的是Jpa的项目为例 , 该项目通过硬编码(配置类)的方式 , 在项目中配置了两个不同的数据源 , 所以...
spring配置数据源有几种方式?分别是什么
PlatformTransactionManager这个是spring提供的用于管理事务的基础接口,其下有一个实现的抽象类AbstractPlatformTransactionManager,我们使用的事务管理类例如DataSourceTransactionManager等都是这个类的子类。我们使用编程式的事务管理流程可能如下:(1) 声明数据源。(2) 声明一个事务管理类,例如:DataSource...
Spring动态配置多数据源基于spring和ibatis的多数据源切换方案_百度知 ...
在使用ibatis时,管理多个数据源曾是一项复杂任务,每次增加一个数据源就需要额外的sql-map-config配置文件,这无疑增加了维护的难度。然而,借助Spring框架,我们可以轻松地解决这个问题,其中Spring的AbstractRoutingDataSource是关键工具。AbstractRoutingDataSource是一个实现了javax.sql.DataSource接口的抽象类...
实用:Spring的多租户数据源管理 AbstractRoutingDataSource!
在实际项目中,我们常常需要在单一服务中访问多个数据源,以满足不同业务需求或实现多租户等功能。这使得系统设计变得复杂,但Spring框架提供了AbstractRoutingDataSource类,为管理多个数据源提供了方便的解决方案。AbstractRoutingDataSource的核心在于其动态路由机制。通过重写其内部方法determineCurrentLookupKey()...
常见问题|事务导致Mybatis plus的多数据源失效
在多事务环境或需要跨数据源操作时,事务的传播特性决定了如何处理多个事务间的交互。Spring框架定义了7种类型的传播行为,每种行为对应不同情况下的事务处理策略。注解演示事物传播特性 为了更直观地理解事务传播特性,以下将通过注解演示不同传播行为的影响。传播特性示例 假设有一个包含三个实现类的案例,...