public class ReadWriteDataSourceProcessor
extends java.lang.Object
implements org.springframework.context.ApplicationContextAware
此类实现了通过AOP切面实现读/写选择:
★★读/写动态数据库选择处理器★★
1、首先读取<tx:advice>事务属性配置
2、对于所有读方法设置 read-only="true" 表示读取操作(以此来判断是选择读还是写库),其他操作都是走写库
如<tx:method name="×××" read-only="true"/>
3、 forceChoiceReadWhenWrite用于确定在如果目前是写(即开启了事务),下一步如果是读,
是直接参与到写库进行读,还是强制从读库读
forceChoiceReadWhenWrite:false 表示目前是写,下一步如果是读,强制参与到写事务(即从写库读)
这样可以避免写的时候从读库读不到数据
通过设置事务传播行为:SUPPORTS实现
forceChoiceReadWhenWrite:true 表示不管当前事务是写/读,都强制从读库获取数据
通过设置事务传播行为:NOT_SUPPORTS实现(连接是尽快释放)
『此处借助了 NOT_SUPPORTS会挂起之前的事务进行操作 然后再恢复之前事务完成的』
4、配置方式
<bean id="readWriteDataSourceTransactionProcessor" class=
"cn.javass.common.datasource.ReadWriteDataSourceProcessor">
<property name="forceChoiceReadWhenWrite" value="false"/>
</bean>
5、支持<tx:advice>和@Transactional注解事务
★★通过AOP切面实现读/写库选择★★
1、首先将当前方法 与 根据之前【读/写动态数据库选择处理器】 提取的读库方法 进行匹配
2、如果匹配,说明是读取数据:
2.1、如果forceChoiceReadOnWrite:true,即强制走读库
2.2、如果之前是写操作且forceChoiceReadOnWrite:false,将从写库进行读取
2.3、否则,到读库进行读取数据
3、如果不匹配,说明默认将使用写库进行操作
4、配置方式
<aop:aspect order="-2147483648" ref=
"readWriteDataSourceTransactionProcessor">
<aop:around pointcut-ref="txPointcut" method=
"determineReadOrWriteDB"/>
</aop:aspect>
4.1、此处order = Integer.MIN_VALUE 即最高的优先级(请参考http://jinnianshilongnian.iteye.com/blog/1423489)
4.2、切入点:txPointcut 和 实施事务的切入点一样
4.3、determineReadOrWriteDB方法用于决策是走读/写库的,请参考
@see ReadWriteDataSourceDecision
@see ReadWriteDataSource
| 构造器和说明 |
|---|
ReadWriteDataSourceProcessor() |
| 限定符和类型 | 方法和说明 |
|---|---|
java.lang.Object |
determineReadOrWriteDB(org.aspectj.lang.ProceedingJoinPoint pjp)
确定当前使用写库还是读库
|
void |
setApplicationContext(org.springframework.context.ApplicationContext applicationContext) |
void |
setForceChoiceReadWhenWrite(boolean forceChoiceReadWhenWrite)
当之前操作是写的时候,是否强制从从库读 默认(false) 当之前操作是写,默认强制从写库读
|
public void setForceChoiceReadWhenWrite(boolean forceChoiceReadWhenWrite)
forceChoiceReadWhenWrite - forceChoiceReadWhenWritepublic java.lang.Object determineReadOrWriteDB(org.aspectj.lang.ProceedingJoinPoint pjp)
throws java.lang.Throwable
确定当前使用写库还是读库
pjp - ProceedingJoinPointjava.lang.Throwable - Throwablepublic void setApplicationContext(org.springframework.context.ApplicationContext applicationContext)
throws org.springframework.beans.BeansException
setApplicationContext 在接口中 org.springframework.context.ApplicationContextAwareorg.springframework.beans.BeansException