- 浏览: 639660 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
liuche20083736:
非常好
从问题看本质: 研究TCP close_wait的内幕 -
xiaopohai85707:
优化算法与原来需求不符
过滤字符的性能调优?挤一挤还是有的 -
kmy_白衣:
生成的area图有时候 标签的数值和图标上看上去的数值不一致。 ...
OpenFlashChart2之恶心文档 -
tom&jerry:
大神,请教一个问题,按名称排序为何无效,用的2.4.3 XPA ...
深入浅出jackrabbit之十三 查询之AST和QT -
jd2bs:
改成精确匹配可以了< filter-mapping &g ...
细谈Ehcache页面缓存的使用
/**
*作者:张荣华
*日期:2008-02-05
**/
前言,这篇文章写于08年12月份,现在发布出来望同行点评
------------------------------------------------------------
本文将要阐述或者讨论的是spring+hibernate和mysql的master-slave模式之间的一些不得不说的故事.
那么开始之前,按照惯例,我们要介绍一下这个两个东西
1,Hibernate,按照惯例,我们不介绍大家都知道的东西.
2, Master-Slave:Mysql的Master-Slave模式是比较常用的数据库lb模型,Master负责数据更新,Slave负责数据读取,在需要备用数据库以及读操作大于写操作的场景下尤其多见.相信熟悉的人一定不在少数.按照惯例,论坛上多次出现的东西,我们只作简要叙述.
在ahuaxuan之前的文章中,曾经多次提到mysql的master-slave,主要是为了解决在流行的ssh框架和master-slave可以无耦合的整合在一起的问题.我们的目的很简单,就是在无需改动我们的业务代码的前提下使用hibernate + master-slave.
之前我们讲到,使用jee中使用master-slave可以有几种方式,
1,mysql-proxy,和应用完全解耦
2,replicationdriver或者使用replication协议头
3,多数据源配置,使用多个jdbcTemplate或者多个hibernateTemplate等.
第一点对应用是最透明的,第二点对业务代码是透明的,第三点需要我们的持久层有较大的改动.同样他们也有各自的优缺点,mysql-proxy在写操作频繁的时候会有一些小问题(一个朋友的公司出现过),replicationdriver和其他driver不能共存,replication协议头比较好,不过和hibernate好像不是很谈得来,而多数据源配置是下下策,ahuaxuan向来讨厌这种做法,如果管理不当,很容易出问题(是指出问题得概率比第一点和第二点大).
以上三种方案对程序员得要求也是各不相同,mysql-proxy对程序员要求最高,replicationdriver或者协议头其次,多数据源最简单.
Ahuaxuan没有尝试过mysql-proxy(因为生产环境早已存在,并且配置好,运维不会让人随便动),不过倒确实有尝试过replicationdriver和replication协议头(它们的本质都是一样的,都是使用ReplicationConnection),根据测试,replicationdriver和replication协议头在使用jdbc或者ibatis是没有什么问题,不过和hibernate在一起得时候就有问题了,mysql服务器cpu使用率无故飙高到80%,应用cpu也上升很多.怕怕+惶惶.而且使用replicationdriver和replication还有一点点小缺点,那就是任何一个ReplicationConnection其实是两个connection(master-connection或者slave connection),哇,真是占着xxx不xxx,虽然只用一个,但是另外一个也不能让别人用,ReplicationConnection不能无耻到这个地步.这可是浪费数据库连接数的典范(其实也没啥,不就是多浪费几个连接嘛,小题大作).
下面我们首先来详细分析一下使用replicationdriver或者replication协议头时的内部细节.
以下是详细的概要步骤(这词儿用的!):
1,用户发起一个http请求,tomcat收到请求之后把从线程池中拿到一个线程,由这个请求线程来负责余下的流程(old io模型,new io模型在这个环节上稍微有点变化,但是接下来的不变)
2,请求线程执行到open session in view filter,拿到一个拿到一个session,通过Threadlocal绑定到该请求线程中.
3,请求线程执行到service,被事务拦截器拦截,在HibernateTransactionManager中, 同时拿到这个session所依赖的connection,而这个时候拿到的connection是数据库连接池的connection实现,也就是说这个connection是一个代理,该代理的target是ReplicationConnection.接着判断当前的事务的读写设置,如果是只读,那么调用ReplicationConnection#setReadonly方法把connection的readonlyflag设置为true.
4,线程在执行setReadonly方法的时候,其实是在调换ReplicationConnection中的currentConnection的引用所指向的对象,原来指向master-connection,如果设置为readonly,那么就重新指向slave-connection,不过事情没有这么简单,调换引用之前,需要把master-connection的状态同时赋值给slave-connection.一共有3个状态需要转移,一个是Catalog,还有一个是autocommit,还有一个是Isolation(注意这里,slave-connection拿到了master-connection的isolation,而它自己原来的isolation却没有保存下来).
5,当前线程退出setReadonly方法,继续在HibernateTransactionManager中游戈,这个时候,准备开始一个事务.
6, 当前线程经过拦截器的前半部分,进入我们的service(假设没有其他代理对象),开始执行我们的业务方法,包含持久化逻辑(查询操作),这里拿到的connection其实是slave-connection.
7, 请求线程退出service方法,回到拦截器的后半部分,这里有一个重要的方法,在提交事务之后,需要resetconnection,代码如下:
我们可以看到,spring是先把事务开始之前的master-connection 的isolationlevel设置回来,然后再改变ReplicationConnection的currentConnection,拿现在的情况来说,spring把slave-connection的isolation重新设置为事务开始之前的isolation(也就是原始的master-connection的isolation),但是问题是事务之前的isolation是设置在master-connection上的.接着,spring又调用setReadonly方法,把currentConnection引用又指向了master-connection(当然,在这之前还需要把slave-connection的状态复制过来),把slave-connection的isolation(同时还有catalog和autocommit)设置给master-connection.不过这个时候,slave-connection的isolation就变成了master-connnection的isolation了,这也许是有问题的,因为这两个connection在开始的时候,isolation有可能是不一样的,但是一次请求之后,它们的isolation级别就变成一样的了.所以这里的代码应该是先setReadOnly,然后再设置isolation.
8,请求线程再次拿到了master-connection,那么一旦以下的流程有延迟加载的情况发生,便会使用这个master-connection来执行查询操作(延迟加载难道应该用master-connection吗,显然不是,延迟加载应该用slave-connection,不过由于这里已经出了事务范围,所以ahuaxuan也没有办法来强制使用slave-connection进行延迟加载了).
9,退出open session in view filter,从当前请求线程中清空这个session和connection,也就是取消connection和请求线程的绑定.关闭session,并建connection重新返回connection pool.
10,从请求线程中拿到返回数据,将请求线程返回线程池,并返回数据到客户端.
总结:使用replicationdriver和replication协议头时,基本上就是以上这个流程,我们可以看到,在上面这个流程中,Master-connection和slave-connection在被交替使用,他们的状态也在整个流程中有2次相互覆盖(而且假设master和slave隔离级别不一样,那么可能目前的spring代码可能会导致一次请求之后改变slave-connection的隔离级别)
由此看来,replicationdriver和replication协议头和spring+hibernate八字确实不太合啊,那只能另寻出路了,mysql-proxy由于政策原因被否决,那么只能在多数据源上下功夫了.
那么怎么分析呢,以下是a某人的自言自语:replicationdriver和replication协议头最大的优点是在驱动上做手脚通过代理connection来透明的选择访问master或者是slave,但是也正因为这个特点,导致hibernate无法一开始(在osiv中)就知道使用哪个connection,也导致了以后一系列的connection转换之类,.
那么如果有办法在osiv中就决定这次请求使用的connection,芑不是很帅气.这样说的话,那么要解决这个问题就是在osiv中确定connection了??,嗯,好像是这么回事,不过在osiv中确定connection好像有点难度啊,咋整啊,那换个思路,在osiv中确定datasource也行啊, 哦,有了.
想到这里,觉悟了,在osiv中确定多数据源的问题的本质就是hibernate+spring的多数据源问题啊.真是苦海无边,回头是岸呀.之前了解过spring2.0之后多了一个类叫作: AbstractRoutingDataSource.那么我们来看一下它的功能:
这段注释告诉我们可以用一个ThreadLocal把一个key绑定到当前线程,然后通过这个key,可以获得当前线程需要的datasource.又是一个代理,ReplicationConnection是代理slave-connection和master-connection,而AbstractRoutingDataSource是代理master-datasource和slave-datasource.既然Juergen Hoeller大叔把标准的使用方法都告诉我们了,我们还有什么担心的呢,按照他老人家的谆谆教导,我们有了以下实现:
1,一个AbstractRoutingDataSource类,控制着应该使用哪个targetdatasource.
2,一个filter,用来覆写原来的osiv的doFilterInternal方法.
3,在我们的spring配置文件上加上:
那么这样一来,我们就可以通过http的method来判断该次请求是使用master还是slave.而且在将session,connection绑定到线程之前就确定了使用master还是slave的connection.
看到这里,地球人都明白了,这种方式和ReplicationConnection里通过readonly来判断使用master-connection还是slave-connection的原理真的是一摸一样啊.小样,别以为穿了个马甲我们就不认识你了.
AbstractRoutingDataSource类虽然很简单,但是却很有效,之前坛子上也有人写过多数据源问题,原理也是一样的,只不过我们当然会用spring自带的东东啦.
总结一下:
本文分为两部分内容,第一部分分析了spring+hibernate在使用opensessioninview的情况下使用replicationdriver或者replication协议头时候的大体流程与内部操作,第二部分分析了spring+hibernate+msyql的master-slave场景下,如何使应用尽可能完美透明的使用mysql的master-slave模式,绕了一圈之后发现动态切换数据源的方法还是比较好的方案,spring2.0之后的版本提供了一个AbstractRoutingDataSource类可以帮助我们快速便捷的实现这个特性.
注:由于ahuaxuan水平有限,理解难免有错误之处,还望不吝指出,不甚感激.
key是指绑定到thread中的那个key,两个请求是两个线程,他们不会相互影响的。
生产环境没有用mysql-proxy,现在运维估计也不敢去动生产环境,现在是master-slave模式,具体是访问master还是slave这个都是由程序控制的
谢谢
我们没有用mysql-proxy,replicationdriver 是支持事务的,ameoba 我没有用过,不过对它我还是比较感兴趣的
谢谢!!我周末查证过,mysql-proxy是支持事务的,你们生产环境不是在用mysql-prxy吗?呵呵
*作者:张荣华
*日期:2008-02-05
**/
前言,这篇文章写于08年12月份,现在发布出来望同行点评
------------------------------------------------------------
本文将要阐述或者讨论的是spring+hibernate和mysql的master-slave模式之间的一些不得不说的故事.
那么开始之前,按照惯例,我们要介绍一下这个两个东西
1,Hibernate,按照惯例,我们不介绍大家都知道的东西.
2, Master-Slave:Mysql的Master-Slave模式是比较常用的数据库lb模型,Master负责数据更新,Slave负责数据读取,在需要备用数据库以及读操作大于写操作的场景下尤其多见.相信熟悉的人一定不在少数.按照惯例,论坛上多次出现的东西,我们只作简要叙述.
在ahuaxuan之前的文章中,曾经多次提到mysql的master-slave,主要是为了解决在流行的ssh框架和master-slave可以无耦合的整合在一起的问题.我们的目的很简单,就是在无需改动我们的业务代码的前提下使用hibernate + master-slave.
之前我们讲到,使用jee中使用master-slave可以有几种方式,
1,mysql-proxy,和应用完全解耦
2,replicationdriver或者使用replication协议头
3,多数据源配置,使用多个jdbcTemplate或者多个hibernateTemplate等.
第一点对应用是最透明的,第二点对业务代码是透明的,第三点需要我们的持久层有较大的改动.同样他们也有各自的优缺点,mysql-proxy在写操作频繁的时候会有一些小问题(一个朋友的公司出现过),replicationdriver和其他driver不能共存,replication协议头比较好,不过和hibernate好像不是很谈得来,而多数据源配置是下下策,ahuaxuan向来讨厌这种做法,如果管理不当,很容易出问题(是指出问题得概率比第一点和第二点大).
以上三种方案对程序员得要求也是各不相同,mysql-proxy对程序员要求最高,replicationdriver或者协议头其次,多数据源最简单.
Ahuaxuan没有尝试过mysql-proxy(因为生产环境早已存在,并且配置好,运维不会让人随便动),不过倒确实有尝试过replicationdriver和replication协议头(它们的本质都是一样的,都是使用ReplicationConnection),根据测试,replicationdriver和replication协议头在使用jdbc或者ibatis是没有什么问题,不过和hibernate在一起得时候就有问题了,mysql服务器cpu使用率无故飙高到80%,应用cpu也上升很多.怕怕+惶惶.而且使用replicationdriver和replication还有一点点小缺点,那就是任何一个ReplicationConnection其实是两个connection(master-connection或者slave connection),哇,真是占着xxx不xxx,虽然只用一个,但是另外一个也不能让别人用,ReplicationConnection不能无耻到这个地步.这可是浪费数据库连接数的典范(其实也没啥,不就是多浪费几个连接嘛,小题大作).
下面我们首先来详细分析一下使用replicationdriver或者replication协议头时的内部细节.
以下是详细的概要步骤(这词儿用的!):
1,用户发起一个http请求,tomcat收到请求之后把从线程池中拿到一个线程,由这个请求线程来负责余下的流程(old io模型,new io模型在这个环节上稍微有点变化,但是接下来的不变)
2,请求线程执行到open session in view filter,拿到一个拿到一个session,通过Threadlocal绑定到该请求线程中.
3,请求线程执行到service,被事务拦截器拦截,在HibernateTransactionManager中, 同时拿到这个session所依赖的connection,而这个时候拿到的connection是数据库连接池的connection实现,也就是说这个connection是一个代理,该代理的target是ReplicationConnection.接着判断当前的事务的读写设置,如果是只读,那么调用ReplicationConnection#setReadonly方法把connection的readonlyflag设置为true.
4,线程在执行setReadonly方法的时候,其实是在调换ReplicationConnection中的currentConnection的引用所指向的对象,原来指向master-connection,如果设置为readonly,那么就重新指向slave-connection,不过事情没有这么简单,调换引用之前,需要把master-connection的状态同时赋值给slave-connection.一共有3个状态需要转移,一个是Catalog,还有一个是autocommit,还有一个是Isolation(注意这里,slave-connection拿到了master-connection的isolation,而它自己原来的isolation却没有保存下来).
5,当前线程退出setReadonly方法,继续在HibernateTransactionManager中游戈,这个时候,准备开始一个事务.
6, 当前线程经过拦截器的前半部分,进入我们的service(假设没有其他代理对象),开始执行我们的业务方法,包含持久化逻辑(查询操作),这里拿到的connection其实是slave-connection.
7, 请求线程退出service方法,回到拦截器的后半部分,这里有一个重要的方法,在提交事务之后,需要resetconnection,代码如下:
public static void resetConnectionAfterTransaction(Connection con, Integer previousIsolationLevel) { Assert.notNull(con, "No Connection specified"); try { // Reset transaction isolation to previous value, if changed for the transaction. if (previousIsolationLevel != null) { if (logger.isDebugEnabled()) { logger.debug("Resetting isolation level of JDBC Connection [" + con + "] to " + previousIsolationLevel); } con.setTransactionIsolation(previousIsolationLevel.intValue()); } // Reset read-only flag. if (con.isReadOnly()) { if (logger.isDebugEnabled()) { logger.debug("Resetting read-only flag of JDBC Connection [" + con + "]"); } con.setReadOnly(false); } } catch (Throwable ex) { logger.debug("Could not reset JDBC Connection after transaction", ex); } }
我们可以看到,spring是先把事务开始之前的master-connection 的isolationlevel设置回来,然后再改变ReplicationConnection的currentConnection,拿现在的情况来说,spring把slave-connection的isolation重新设置为事务开始之前的isolation(也就是原始的master-connection的isolation),但是问题是事务之前的isolation是设置在master-connection上的.接着,spring又调用setReadonly方法,把currentConnection引用又指向了master-connection(当然,在这之前还需要把slave-connection的状态复制过来),把slave-connection的isolation(同时还有catalog和autocommit)设置给master-connection.不过这个时候,slave-connection的isolation就变成了master-connnection的isolation了,这也许是有问题的,因为这两个connection在开始的时候,isolation有可能是不一样的,但是一次请求之后,它们的isolation级别就变成一样的了.所以这里的代码应该是先setReadOnly,然后再设置isolation.
8,请求线程再次拿到了master-connection,那么一旦以下的流程有延迟加载的情况发生,便会使用这个master-connection来执行查询操作(延迟加载难道应该用master-connection吗,显然不是,延迟加载应该用slave-connection,不过由于这里已经出了事务范围,所以ahuaxuan也没有办法来强制使用slave-connection进行延迟加载了).
9,退出open session in view filter,从当前请求线程中清空这个session和connection,也就是取消connection和请求线程的绑定.关闭session,并建connection重新返回connection pool.
10,从请求线程中拿到返回数据,将请求线程返回线程池,并返回数据到客户端.
总结:使用replicationdriver和replication协议头时,基本上就是以上这个流程,我们可以看到,在上面这个流程中,Master-connection和slave-connection在被交替使用,他们的状态也在整个流程中有2次相互覆盖(而且假设master和slave隔离级别不一样,那么可能目前的spring代码可能会导致一次请求之后改变slave-connection的隔离级别)
由此看来,replicationdriver和replication协议头和spring+hibernate八字确实不太合啊,那只能另寻出路了,mysql-proxy由于政策原因被否决,那么只能在多数据源上下功夫了.
那么怎么分析呢,以下是a某人的自言自语:replicationdriver和replication协议头最大的优点是在驱动上做手脚通过代理connection来透明的选择访问master或者是slave,但是也正因为这个特点,导致hibernate无法一开始(在osiv中)就知道使用哪个connection,也导致了以后一系列的connection转换之类,.
那么如果有办法在osiv中就决定这次请求使用的connection,芑不是很帅气.这样说的话,那么要解决这个问题就是在osiv中确定connection了??,嗯,好像是这么回事,不过在osiv中确定connection好像有点难度啊,咋整啊,那换个思路,在osiv中确定datasource也行啊, 哦,有了.
想到这里,觉悟了,在osiv中确定多数据源的问题的本质就是hibernate+spring的多数据源问题啊.真是苦海无边,回头是岸呀.之前了解过spring2.0之后多了一个类叫作: AbstractRoutingDataSource.那么我们来看一下它的功能:
Abstract DataSource implementation that routes {@link #getConnection()} calls to one of various target DataSources based on a lookup key. The latter is usually (but not necessarily) determined through some thread-bound transaction context.
这段注释告诉我们可以用一个ThreadLocal把一个key绑定到当前线程,然后通过这个key,可以获得当前线程需要的datasource.又是一个代理,ReplicationConnection是代理slave-connection和master-connection,而AbstractRoutingDataSource是代理master-datasource和slave-datasource.既然Juergen Hoeller大叔把标准的使用方法都告诉我们了,我们还有什么担心的呢,按照他老人家的谆谆教导,我们有了以下实现:
1,一个AbstractRoutingDataSource类,控制着应该使用哪个targetdatasource.
/** * * @author ahuaxuan * @date 2008-6-7 * @version $id$ */ public class MasterSlaveRoutingDataSource extends AbstractRoutingDataSource{ private static transient Log logger = LogFactory.getLog(MasterSlaveRoutingDataSource.class); //DbType是一个标示符,代表datasource的key private static final ThreadLocal<DbType> contextHolder = new ThreadLocal<DbType>(); public static void setDbType(DbType type) { contextHolder.set(type); } public static DbType getDbType() { return contextHolder.get(); } public static void clearCustomerType() { contextHolder.remove(); } protected Object determineCurrentLookupKey() { Object o = contextHolder.get(); if (logger.isDebugEnabled()) { logger.debug("------- The current data source is " + o); } return o != null ? o : DbType.Slave; } public boolean isWrapperFor(Class iface) throws SQLException { return false; } public Object unwrap(Class iface) throws SQLException { return null; } }
2,一个filter,用来覆写原来的osiv的doFilterInternal方法.
/** * hiddenPostSearch field means if we use post method to do searching, use slave datasource * * @author ahuaxuan * @date 2008-6-7 * @version $id$ */ public class MsOpenSessionInViewFilter extends OpenSessionInViewFilter{ private static final String SLAVE_METHOD = "get"; private static final String HIDDEN_FIELD_NAME = "hiddenPostSearch_001"; protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (SLAVE_METHOD.equals(request.getMethod()) || SLAVE_METHOD.equals(request.getParameter(HIDDEN_FIELD_NAME))) { MasterSlaveRoutingDataSource.setDbType(DbType.Slave); } else { MasterSlaveRoutingDataSource.setDbType(DbType.Master); } super.doFilterInternal(request, response, filterChain); } }
3,在我们的spring配置文件上加上:
<bean id="dataSource" class="com.xx.MasterSlaveRoutingDataSource"> <property name="targetDataSources"> <map key-type="com.xx.DbType"> <entry key="Master" value-ref="writeDataSource"/> <entry key="Slave" value-ref="readDataSource"/> </map> </property> <property name="defaultTargetDataSource" ref="readDataSource"/> </bean>
那么这样一来,我们就可以通过http的method来判断该次请求是使用master还是slave.而且在将session,connection绑定到线程之前就确定了使用master还是slave的connection.
看到这里,地球人都明白了,这种方式和ReplicationConnection里通过readonly来判断使用master-connection还是slave-connection的原理真的是一摸一样啊.小样,别以为穿了个马甲我们就不认识你了.
AbstractRoutingDataSource类虽然很简单,但是却很有效,之前坛子上也有人写过多数据源问题,原理也是一样的,只不过我们当然会用spring自带的东东啦.
总结一下:
本文分为两部分内容,第一部分分析了spring+hibernate在使用opensessioninview的情况下使用replicationdriver或者replication协议头时候的大体流程与内部操作,第二部分分析了spring+hibernate+msyql的master-slave场景下,如何使应用尽可能完美透明的使用mysql的master-slave模式,绕了一圈之后发现动态切换数据源的方法还是比较好的方案,spring2.0之后的版本提供了一个AbstractRoutingDataSource类可以帮助我们快速便捷的实现这个特性.
注:由于ahuaxuan水平有限,理解难免有错误之处,还望不吝指出,不甚感激.
评论
9 楼
ahuaxuan
2010-12-09
blackhost 写道
对于楼主的这种方式,我有一个不小的疑问,盼望楼主解答!
这个多数据源的配置,取决于用户在MasterSlaveRoutingDataSource中时,根据Key获取是从master还是从Slave取Connection。
问题是,假如两个不同的用户,不同的Session,在取Connection钱,分别作了Master和Slave的请求,假如两个请求非常快。比如如下:
A-》Master-》getHiberateTemplate();
b-》Slave->getHiberateTemplate();
在A实际获取Connection之前,B抢先改变了MasterSlaveRoutingDataSource的key值,则A就取到了Slave的Connnection,而实际上A期望得到的是Master
请问这个问题不会发生吗?
这个多数据源的配置,取决于用户在MasterSlaveRoutingDataSource中时,根据Key获取是从master还是从Slave取Connection。
问题是,假如两个不同的用户,不同的Session,在取Connection钱,分别作了Master和Slave的请求,假如两个请求非常快。比如如下:
A-》Master-》getHiberateTemplate();
b-》Slave->getHiberateTemplate();
在A实际获取Connection之前,B抢先改变了MasterSlaveRoutingDataSource的key值,则A就取到了Slave的Connnection,而实际上A期望得到的是Master
请问这个问题不会发生吗?
key是指绑定到thread中的那个key,两个请求是两个线程,他们不会相互影响的。
8 楼
blackhost
2010-09-21
对于楼主的这种方式,我有一个不小的疑问,盼望楼主解答!
这个多数据源的配置,取决于用户在MasterSlaveRoutingDataSource中时,根据Key获取是从master还是从Slave取Connection。
问题是,假如两个不同的用户,不同的Session,在取Connection钱,分别作了Master和Slave的请求,假如两个请求非常快。比如如下:
A-》Master-》getHiberateTemplate();
b-》Slave->getHiberateTemplate();
在A实际获取Connection之前,B抢先改变了MasterSlaveRoutingDataSource的key值,则A就取到了Slave的Connnection,而实际上A期望得到的是Master
请问这个问题不会发生吗?
这个多数据源的配置,取决于用户在MasterSlaveRoutingDataSource中时,根据Key获取是从master还是从Slave取Connection。
问题是,假如两个不同的用户,不同的Session,在取Connection钱,分别作了Master和Slave的请求,假如两个请求非常快。比如如下:
A-》Master-》getHiberateTemplate();
b-》Slave->getHiberateTemplate();
在A实际获取Connection之前,B抢先改变了MasterSlaveRoutingDataSource的key值,则A就取到了Slave的Connnection,而实际上A期望得到的是Master
请问这个问题不会发生吗?
7 楼
niyunjiu
2009-03-15
ahuaxuan 写道
生产环境没有用mysql-proxy,现在运维估计也不敢去动生产环境,现在是master-slave模式,具体是访问master还是slave这个都是由程序控制的
谢谢
6 楼
ahuaxuan
2009-03-09
生产环境没有用mysql-proxy,现在运维估计也不敢去动生产环境,现在是master-slave模式,具体是访问master还是slave这个都是由程序控制的
5 楼
niyunjiu
2009-03-09
ahuaxuan 写道
我们没有用mysql-proxy,replicationdriver 是支持事务的,ameoba 我没有用过,不过对它我还是比较感兴趣的
谢谢!!我周末查证过,mysql-proxy是支持事务的,你们生产环境不是在用mysql-prxy吗?呵呵
4 楼
ahuaxuan
2009-03-06
我们没有用mysql-proxy,replicationdriver 是支持事务的,ameoba 我没有用过,不过对它我还是比较感兴趣的
3 楼
niyunjiu
2009-03-06
请问博主,
1、到目前为止,你们的mysql-proxy还稳定吗?
2、replicationdriver 支持事务吗?我们用mysql innodb引擎,所以要求支持事务。
ameoba类似于mysql-proxy,比mysql-proxy好,唯一的缺点就是不支持事务。
谢谢!
1、到目前为止,你们的mysql-proxy还稳定吗?
2、replicationdriver 支持事务吗?我们用mysql innodb引擎,所以要求支持事务。
ameoba类似于mysql-proxy,比mysql-proxy好,唯一的缺点就是不支持事务。
谢谢!
2 楼
ahuaxuan
2009-03-02
进入事务得方法不一定会设置成非只读,以为有只读事务,也就是说事务还是有得,延迟加载得时候应该选择slave得datasource,我也是这样做得
1 楼
zhang_ly520
2009-03-02
最近也在做这方便的研究,看了文章后受益良多。
因为对于spring底层了解的不多,我想知道要是在spring中配置了事务管理,拦截了所有需要事务的方法的话,哪么进入事务的方法是否都被设置成“非只读”呢?哪么其他的方法,比如“get”都不进入事务也就都是“只读”,哪么延迟加载的时候是不是应该使用slave的连接,否则我所有的方法可能都是通过master连接执行的。
不知道能看懂我说的不?
因为对于spring底层了解的不多,我想知道要是在spring中配置了事务管理,拦截了所有需要事务的方法的话,哪么进入事务的方法是否都被设置成“非只读”呢?哪么其他的方法,比如“get”都不进入事务也就都是“只读”,哪么延迟加载的时候是不是应该使用slave的连接,否则我所有的方法可能都是通过master连接执行的。
不知道能看懂我说的不?
发表评论
-
过滤字符的性能调优?挤一挤还是有的
2010-05-29 05:54 3610/* *auth ... -
弃成见,反省,并重新认识struts.i18n.encoding
2008-12-24 15:42 3882[size=medium]之前和大家讨论了struts2.0中 ... -
关键字:查询,事务,粒度
2008-08-22 17:05 5139[size=medium]/** *作者: ... -
看看mina和memcached的联姻(适合不同语言客户端,高并发?)
2008-07-21 17:06 7985[size=medium]/** * 作者:张荣华 * 日 ... -
如何解决mysql的master-slave模式中ReplicationDriver的使用问题
2008-06-19 18:23 8220/** * 作者:张荣华 * 日期:2008-6-19 ... -
别装了,难道你们不想把properties直接注入到object中去(spring-plugin)?
2008-04-09 18:01 3651[size=small]/** *作者:张荣华(ahuaxu ... -
用jamon来监控你的sql执行效率
2008-02-25 15:48 3717/** *作者:张荣华 *日期:2008-2-25 ... -
java同msn的通信,大家想想用途吧
2007-11-24 17:14 2514程序员的生活真是单调,除了编程还是编程,工作日 ... -
EAI企业应用集成场景及解决方案
2007-09-21 18:21 3155/** *作者:张荣华(ahuaxuan) *2007-9 ... -
quartz和应用的集群问题
2007-08-21 18:36 12818之前看到很多关于quartz的讨论,尤其是关于quar ... -
优化程序之前,可用Jamon来监测你的Spring应用
2007-08-14 18:14 8125/** *作者:张荣华(ahuaxuan) *2007-8-1 ... -
请问责任链真的是一种设计模式吗
2007-07-26 18:12 9414坛子上讨论设计模式的也挺多的,但是关于这个责任链模式还没有人提 ... -
把ActiveMQ的控制台整合到你的web程序中
2007-07-19 12:06 8831在使用ActiveMQ的时候把ActiveMQ的控制台整 ... -
设计模式之:解剖观察者模式
2007-07-17 16:12 6868[size=9] 论坛上很多人都 ... -
java邮件:在简单和复杂之间的方案
2007-07-11 18:07 7585/** *作者:张荣华(ahuaxu ... -
强强连手, 在模板中分页,看Freemarker和displaytag的结合
2007-07-09 09:22 6927/** *作者:张荣华(ahuaxuan) *2007-0 ... -
解惑:在spring+hibernate中,只读事务是如何被优化的。
2007-06-28 18:22 7622/** *作者:张荣华(ahuaxuan) *2007- ... -
让webwork零配置 第二章(实现)(实例已放出,大家可以下载运行)
2007-06-25 09:23 5709/** *作者:张荣华(ahuaxuan) *2007-0 ... -
让webwork2零配置,第一章(主贴再次更新)
2007-06-18 15:41 13380/** *作者:张荣华(ahuaxuan) *2007-0 ... -
Spring声明式事务管理源码解读之事务提交
2007-06-11 09:19 7286/** *作者:张荣华(ahuaxuan) *2007-0 ...
相关推荐
标题中的"Modbus-Master-Slave-for-Arduino-master.zip_Master/Slave_arduino"指出这是一个关于Arduino平台的Modbus主从通信库。Modbus是一种广泛使用的工业通信协议,允许不同设备之间交换数据,尤其在自动化系统中...
在`sharding-master-slave`项目中,我们将看到如何将`Sharding-JDBC`与`SpringBoot`相结合,以实现数据的高效管理和访问。 1. **分库分表策略** `Sharding-JDBC`支持自定义分片策略,这在`描述`中提到。通常,分片...
在分布式系统中,为了确保数据的高可用性和容错性,MongoDB提供了两种复制模式:master-slave(主从模式)和master-master(主主模式)。本实验将深入探讨这两种模式的工作原理、设置方法以及它们在实际应用中的优...
ActiveMQ Master-Slave集群是一种高可用性和容错性的解决方案,确保即使主节点(Master Broker)发生故障,消息也不会丢失,因为它们已经被复制到从节点(Slave Broker)。这种配置是ActiveMQ推荐的策略之一,提供了...
在企业级开发中,主从关系(Master-Slave)是一种常见的架构模式,广泛应用于数据库复制、分布式系统、任务调度等多个领域。这种模式的核心在于,一个主节点(Master)负责处理请求、执行关键操作或决策制定,而一个...
在ActiveMQ中,主要有三种Master-Slave实现:Pure Master Slave、Shared File System Master Slave和JDBC Master Slave。这里主要讨论的是JDBC Master Slave模式,它依赖于数据库来确定哪个Broker是Master,哪个是...
标题“spring-master-slave-commondao”暗示我们正在讨论一个与Spring框架相关的项目,可能是用于数据库主从复制或分片的通用数据访问对象(DAO)实现。这个项目可能提供了一种方式来管理和操作在主库和从库之间的...
第1步 master-slave1和slave2配置网络和搭建Hadoop集群环境.docx
** activemq master-slave 架构与 NFSV4 的集成** 在企业级消息传递系统中,Apache ActiveMQ 是一个广泛使用的开源消息代理,它提供了可靠的消息传递服务。为了实现高可用性和容错性,ActiveMQ 支持主从(master-...
本篇文章将深入探讨如何在Arduino平台上实现Modbus主从通信,基于"Modbus-Master-Slave-for-Arduino-master"库,帮助开发者更好地理解和应用这一强大的工具。 一、Modbus协议简介 Modbus是一种公开的通信协议,由...
本文将深入探讨一个名为"Master-slave-alarm-system"的项目,该系统旨在通过主从结构实现对温度的实时检测,并具备上位机报警功能。我们将分析系统的架构、工作原理以及其核心组件,为理解此类系统提供详尽的解析。 ...
这个“modbus-master-slave模拟软件”就是专为测试和调试基于Modbus协议的系统而设计的工具。 首先,我们来理解一下Modbus协议的基础。Modbus协议是1979年由施耐德电气公司开发的一种串行通信协议,它定义了主设备...
【源码】基于python+scrapy+redis实现主从式master-slave爬虫.zip 【源码】基于python+scrapy+redis实现主从式master-slave爬虫.zip 【源码】基于python+scrapy+redis实现主从式master-slave爬虫.zip 【源码】基于...
标题“Master_slave_multi_machine.rar_Master-slave_Master/Slave_multi m”暗示了我们正在讨论的焦点是关于主从结构在多机器环境中的应用。 描述“主从多机通信系统问题研究建模及其实性研究”表明我们将深入探讨...
"Master-_-Slave-Core"标题暗示了这是一个关于I2C主从核心的项目,其中包含了一套用于实现I2C主从模式的代码。 I2C协议是由飞利浦(现NXP半导体)在1980年代初设计的,它允许在一个总线上连接多个设备,减少了所需...
### DeviceNet Master-Slave Module (Q系列) #### 概述 本文档旨在提供有关DeviceNet Master-Slave模块QJ71DN91的重要安全和操作指导。本产品为三菱可编程逻辑控制器(PLC)的一个扩展模块,用于实现DeviceNet网络...
【Master-Slave模式详解】 在Java并发编程中,Master-Slave模式是一种常见的多线程处理策略,它借鉴了“分而治之”的思想,将一个大任务分解为多个小任务,分配给多个工作线程(Slave)执行,由一个主控线程...
《FreeModbus_Slave-Master-RTT-STM32-master_stm32mastermodbus_stm32:深入理解MODBUS通信在STM32中的应用》 MODBUS通信协议,作为工业自动化领域的标准通信协议,因其简单、开放、易实现的特点,在嵌入式系统...
jenkins-jnlp-slave镜像
【标题】"master-slave-i-o-keypad-lcd-master_arduino_" 涉及的是一个基于Arduino的主从式I/O、键盘和LCD显示的项目。这个项目的主要目的是通过Arduino来构建一个主从通信系统,其中主设备控制从设备,从设备接收...