技术标签: spring理解
当数据量越来越多的时候,我们就会开始考虑跨库查询,读写分离,之前对于数据库读写分离有过一定的了解,但是这里面存在着一个问题,就是A库中有a表,B库中有b表,那如果b表出现了异常,a表这个时候怎么回滚呢?当在一个数据库中直接用事务很好的处理,那如果在多个数据源中呢?其实原理是一样的。
对于一些较大的规模的应用,单个数据源已经无法支撑起庞大的用户量,需要引入多数据源,水平层面进行分库分表,降低DB的负载。另外,跨库意味着单DB的事务就失效了,所以J2EE提出了JTA,分布式事务管理,简单的说,就是分2步提交,实际它有2个容器来管理,一个资源管理器,一个事务管理,在第一个阶段中,所有参与全局事务的节点都开始准备,告诉事务管理器它们准备好提交了。第二阶段,事务管理器告诉资源管理器执行commit或者rollback,如果任何一个节点显示不能commit,那么所有的节点全部rollback,下面我们来实现分布式事务:
第一步:XA数据源定义
选定义一个抽象的父类源,这样子类可以直接继承
<!-- 两个数据源的功用配置,方便下面直接引用 --> <bean id="abstractXADataSource" class="com.atomikos.jdbc.AtomikosDataSourceBean" destroy-method="close"> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource"/> <property name="poolSize" value="10" /> <property name="minPoolSize" value="10"/> <property name="maxPoolSize" value="30"/> <property name="borrowConnectionTimeout" value="60"/> <property name="reapTimeout" value="20"/> <!-- 最大空闲时间 --> <property name="maxIdleTime" value="60"/> <property name="maintenanceInterval" value="60" /> <property name="loginTimeout" value="60"/> <property name="logWriter" value="60"/> <property name="testQuery"> <value>select 1</value> </property> </bean>
master源
<bean id="masterSource" parent="abstractXADataSource"> <property name="uniqueResourceName"> <value>master</value> </property> <property name="xaDataSourceClassName" value="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" /> <property name="xaProperties"> <props> <prop key="user">库用户名</prop> <prop key="password">库密码</prop> <prop key="URL">master库连接</prop> </props> </property> </bean>
slave源
<bean id="slaveSource" parent="abstractXADataSource"> <property name="uniqueResourceName"> <value>slave</value> </property> <property name="xaDataSourceClassName"> <value>com.mysql.jdbc.jdbc2.optional.MysqlXADataSource</value> </property> <property name="xaProperties"> <props> <prop key="user">库用户名</prop> <prop key="password">库密码</prop> <prop key="URL">slave库连接</prop> </props> </property> </bean>
基于spring的AbstractRoutingDataSource动态数据路由定义
<bean id="dataSource" class="com.icz.carcare.datasource.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.String"> <!-- write 数据更新和实时数据查询--> <entry key="master" value-ref="masterSource"/> <!-- read 非实时数据查询--> <entry key="slave" value-ref="slaveSource"/> </map> </property> <property name="defaultTargetDataSource" ref="masterSource"/> <!-- 默认使用master的数据源 --> </bean>
mybatis中进行ORM映射
<bean id="sqlSessionFactorya" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="masterSource"/> <!-- 自动扫描sqlmaps目录, 省掉Configuration.xml里的手工配置 --> <property name="mapperLocations" value="classpath*:Msqlmaps/*.xml" /> </bean> <bean id="sqlSessionFactoryb" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="slaveSource" /> <!-- 自动扫描sqlmaps目录, 省掉Configuration.xml里的手工配置 --> <property name="mapperLocations" value="classpath*:Msqlmaps/*.xml" /> </bean>配置sessionTemplate模板
<!-- 配置自定义的SqlSessionTemplate模板,注入相关配置 --> <bean id="sqlSessionTemplate" class="com.icz.carcare.sqlSessionTemplate.CustomSqlSessionTemplate"> <constructor-arg ref="sqlSessionFactorya" /> <property name="targetSqlSessionFactorys"> <map> <entry value-ref="sqlSessionFactorya" key="master"/> <entry value-ref="sqlSessionFactoryb" key="slave"/> </map> </property> </bean>jta配置
<bean id="atomikosTransactionManager" class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" destroy-method="close"> <property name="forceShutdown"> <value>true</value> </property> </bean> <bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> <property name="transactionTimeout" value="300" /> </bean> <bean id="springTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager"> <ref bean="atomikosTransactionManager" /> </property> <property name="userTransaction"> <ref bean="atomikosUserTransaction" /> </property> </bean>
以上xml配置完了,现在就可以去实现跨库事务的代码编写了。
下面我们来讲讲分布式事务原理理解。
Innodb存储引擎支持XA事务,通过XA事务可以支持分布式事务的实现。分布式事务指的是允许多个独立的事务资源参与一个全局事务中。
全局事务要求其中所参与的事务要么提交,要么全部回滚。
XA事务允许不同数据库之间的分布式事务,如:一台服务器是Mysql数据库,一台是Oracle的,又有可能还有一台是sqlserver的,只要参与全部事务中每个节点都支持XA事务。分布式事务可能在银行系统的转账中比较常见,
#bank shanghai
update user_account set money=money+100 where user='xiaozhang';
#bank beijing
update user_account set money=money-100 where user='xiaoli';
像这种情况就是,要不都提交,要不都回滚。在任何一个节点出问题都会造成严重的问题,1 xiaozhang的账号收到了钱,但是xiaoli没有扣款 2.xiaozhang的账号没有收到钱,但是xiaoli扣款了
分布式事务是由一个或者多个resource Managerd,一个事务管理器transaction manage以及一个应用程序application Program组成。
资源管理器:提供事务资源的方法,通常一个数据库就是一个资源管理器
事务管理器:协调参与全部事务各个事务,需要和参与全局事务中的资源管理员进行通信。
应用程序:定义事务的边界,指定全局事务中的操作。
在mysql分布式事务中,资源管理器就是mysql数据库,事务管理器为连接到mysql服务器的客户端。
将shape文件转成geojson格式使用ogr2ogr.exe工具E:\Program Files\PostgreSQL\9.5\bin>ogr2ogr.exe -f GEOJSON G:\fl\data\shp1\gridPoly.json G:\fl\data\shp1\gridPoly.shp
浅析MRv1与MRv2的API兼容性1. 基本概念MRv1是Hadoop 1.X中的MapReduce实现,它由编程模型(新旧编程接口)、运行时环境(由JobTracker和TaskTracker组成)和数据处理引擎(MapTask和ReduceTask)三部分组成。该框架在扩展性、容错性(JobTracker单点)和多框架(仅支持MapReduce一种计算模型)等支持方面支持不足。关于M
python 列表删除所有指定元素的方法如下所示:a = [1,1,1,2,3,45,1,2,1]a.remove(1)result: [1,1,2,3,45,1,2,1]while 1 in a:a.remove(1)result: [2,3,45,2]以上这篇python 列表删除所有指定元素的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。您可能感兴趣的文章..._python删除列表中所有的某个值
【深度学习-图像处理&分类篇】pytorch&Training a Classifier官网分类demo详细复现Training a Classifier利用官方的代码加载查看数据集实例化网络完整的训练代码:train.py 文件Reference:Training a ClassifierPytorch 安装进入官网:: Pytorch.官网链接.选择版本,,方式,(pip安装)pip3 install torch==1.8.1+cu102 torchvision==0_letnet图像处理例子
显示行号|选择喜欢的代码风格默认GitHubDuneLakeSidePlateauVibrantBlueEightiesTranquilpip 命令是 Python 软件包管理器。pip 命令安装:-bash: pip command not found#Debianapt-get install python-pip#Ubuntuapt-get install python-pip#Arch L..._linux pip: command not found
判断一个数独是否合法,未填的空格用字符 ' . ' 表示。该数独有解并不是必要的。e.g. 如图合法数独,输入["53..7....","6..195...",".98....6.","8...6...3","4..8.3..1","7...2...6",".6....28.","...419..5","....8..79"]返回 true。我依然使用死办法解决,而且进行..._e.g. leetcode
Linux正在成为开发人员的编程天堂,它是一个开放源代码和免费的操作系统。 Turbo C编译器已经是一种用于编译程序的旧方法,因此让我们的程序员转向Linux寻求新的编程环境。在本文中,我们将解释如何编写,编译和运行简单的C程序。这将成为您转入可以在Linux上编写和执行的更复杂和有用的C程序的基础。我们已经在Ubuntu 18.04 LTS系统上运行了本文中提到的步骤和命令。我们将使用Linu..._linux运行c语言里面使用linux命令
/* Copyright (c)2016,烟台大学计算机与控制工程学院 All rights reserved. 文件名称:查找.cpp 作 者: 陈朋 完成日期:2016年12月15日 版 本 号:v1.0 问题描述: 输入描述:无 程序输出:若干 */ #include stdio.h> #include mal
函数介绍:char *fgets(char *buf, int size, FILE *fp);fgets的功能是从文件中读取一行。参数buf是一个字符串,用于保存从文件中读到的数据。参数size是打算读取内容的长度。参数fp是待读取文件的文件指针。调用fgets函数如果成功的读取到内容,函数返回buf,如果读取错误或文件已结束,返回空,即0。如果fgets返回空,可以认为是文件结束而不是发生了错误,因为发生错误的情况极少出现。函数理解:读取一次 ≠ 读取一行读取一行内容需要读取一次或以上_fgets成功判断
浏览器的flash插件,firefox无力回天,改用chrome
将java程序安装为系统服务_把jar包作为服务
单视图几何Vanish Point(消失点/灭点)计算方法——Robert_T_Collins(罗伯特·柯林斯)算法_灭点计算