Springダイナミックスイッチングデータベースサポートトランザクション

4632 ワード

プロジェクトにはmysqlの複数のライブラリがあり、コード内で同じ方法で異なるテーブルを操作する可能性があります.ネットでいろいろな方法を学びました.ざっとまとめてみました.
1.mycat、cobarなどの分散型データベースミドルウェア.
よくサポートできますが、重量級すぎて、私たちのプロジェクトには少し役に立たないです.
2.springのAbstractRoutingDataSourceでデータベース接続の切り替えを実現します.
データ・ソースは動的に切り替えることができますが、トランザクションに影響があり、JTAでトランザクションの一貫性を実現できますが、効率は低いです.また、プロジェクトトランザクションは、単一のライブラリで一貫してニーズを満たすことができます.だからこの方式を採用しました.
具体的な実装手順は次のとおりです.
1)springのプロファイルに複数のデータソースを構成します.

























2)動的データソースの定義









3)動的データソースと補助クラスの定義
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
String type = DataSourceContextHolder.getDataSourceType();
return type;
}
}

public class DataSourceContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal();

/**
* @Description:        
* @param dataSourceType
*      
* @return void
* @throws
*/
public static void setDataSourceType(String dataSourceType) {
contextHolder.set(dataSourceType);
}

/**
* @Description:        
* @param
* @return String
* @throws
*/
public static String getDataSourceType() {
return contextHolder.get();
}

/**
* @Description:        
* @param
* @return void
* @throws
*/
public static void clearDataSourceType() {
contextHolder.remove();
}
}

4)トランザクション・マネージャのデータ・ソースを動的データ・ソースに変更し、トランザクション・ノートのソートを2に指定します.データ・ソースを切り替える注釈を1に指定します.これにより、トランザクションの前にデータ・ソースを切り替えます.そうしないと、トランザクションの後に切り替えると無効になります.





5)定義はデータベースの注釈とaop切面を切り替えて、指定は1に並べ替えて、ここで疑問があって、切点を通じて代理方法の注釈データを取得して、私は反射を使って、しかしネット上で直接パラメータとして伝わることができると言って、私はずっと試験に成功していないで、どこに間違いがあるか分からないで、後続のどの大神が指導して、分かち合うことができます.
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface DataSource {
String name();

}

@Component
@Aspect
@Order(1)
public class DataSourceProxy {

@Before(value="@annotation(com.futuren.wzk.common.datasource.DataSource)")
public void before(JoinPoint jp) {
String methodName = jp.getSignature().getName();
Method[] methods = jp.getTarget().getClass().getMethods();
for(Method method : methods) {
if(method.getName().equals(methodName)) {
DataSource ds = method.getAnnotation(DataSource.class);
DataSourceContextHolder.setDataSourceType(ds.name());
}
}
}
}

6)プロジェクトでの使用
@Override
@Transactional
@DataSource(name="ucenter")
public int addUser(User user) {
userMapper.insert(user);
return user.getUid();
}

この方法は、単一ライブラリトランザクションのみをサポートし、複数ライブラリトランザクションを使用する場合はJTAを導入するか、他のカスタムインプリメンテーションを導入する可能性があります.あるいは私が知らない技術です.討論を歓迎します!