feat: initial iShare project code
This commit is contained in:
33
pigx-common/pigx-common-seata/pom.xml
Normal file
33
pigx-common/pigx-common-seata/pom.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<version>5.2.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>pigx-common-seata</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<description>pigx 分布式事务处理模块</description>
|
||||
|
||||
<dependencies>
|
||||
<!--核心依赖-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
</dependency>
|
||||
<!-- seata-->
|
||||
<dependency>
|
||||
<groupId>com.alibaba.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
|
||||
</dependency>
|
||||
<!-- seata kryo 序列化-->
|
||||
<dependency>
|
||||
<groupId>io.seata</groupId>
|
||||
<artifactId>seata-serializer-kryo</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.pig4cloud.pigx.common.seata.config;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.factory.YamlPropertySourceFactory;
|
||||
import io.seata.spring.annotation.datasource.EnableAutoDataSourceProxy;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
|
||||
/**
|
||||
* Seata 配置类
|
||||
*
|
||||
* @author lengleng
|
||||
* @date 2022/3/29
|
||||
*/
|
||||
@PropertySource(value = "classpath:seata-config.yml", factory = YamlPropertySourceFactory.class)
|
||||
@EnableAutoDataSourceProxy(useJdkProxy = true)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class SeataAutoConfiguration {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2022/3/29
|
||||
*/
|
||||
package io.seata.spring.util;
|
||||
|
||||
import io.seata.common.util.CollectionUtils;
|
||||
import io.seata.rm.tcc.remoting.parser.DubboUtil;
|
||||
import org.springframework.aop.TargetSource;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.framework.AdvisedSupport;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Proxy tools base on spring 主要解决 v1.4.2 兼容性问题 https://github.com/seata/seata/issues/3709
|
||||
*
|
||||
* @author zhangsen
|
||||
*/
|
||||
public class SpringProxyUtils {
|
||||
|
||||
private SpringProxyUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find target class class.
|
||||
* @param proxy the proxy
|
||||
* @return the class
|
||||
* @throws Exception the exception
|
||||
*/
|
||||
public static Class<?> findTargetClass(Object proxy) throws Exception {
|
||||
if (proxy == null) {
|
||||
return null;
|
||||
}
|
||||
if (AopUtils.isAopProxy(proxy) && proxy instanceof Advised) {
|
||||
// #issue 3709
|
||||
final TargetSource targetSource = ((Advised) proxy).getTargetSource();
|
||||
if (!targetSource.isStatic()) {
|
||||
return targetSource.getTargetClass();
|
||||
}
|
||||
return findTargetClass(targetSource.getTarget());
|
||||
}
|
||||
return proxy.getClass();
|
||||
}
|
||||
|
||||
public static Class<?>[] findInterfaces(Object proxy) throws Exception {
|
||||
if (AopUtils.isJdkDynamicProxy(proxy)) {
|
||||
AdvisedSupport advised = getAdvisedSupport(proxy);
|
||||
return getInterfacesByAdvised(advised);
|
||||
}
|
||||
else {
|
||||
return new Class<?>[] {};
|
||||
}
|
||||
}
|
||||
|
||||
private static Class<?>[] getInterfacesByAdvised(AdvisedSupport advised) {
|
||||
Class<?>[] interfaces = advised.getProxiedInterfaces();
|
||||
if (interfaces.length > 0) {
|
||||
return interfaces;
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException("Find the jdk dynamic proxy class that does not implement the interface");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets advised support.
|
||||
* @param proxy the proxy
|
||||
* @return the advised support
|
||||
* @throws Exception the exception
|
||||
*/
|
||||
public static AdvisedSupport getAdvisedSupport(Object proxy) throws Exception {
|
||||
Field h;
|
||||
if (AopUtils.isJdkDynamicProxy(proxy)) {
|
||||
h = proxy.getClass().getSuperclass().getDeclaredField("h");
|
||||
}
|
||||
else {
|
||||
h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
|
||||
}
|
||||
h.setAccessible(true);
|
||||
Object dynamicAdvisedInterceptor = h.get(proxy);
|
||||
Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
|
||||
advised.setAccessible(true);
|
||||
return (AdvisedSupport) advised.get(dynamicAdvisedInterceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is proxy boolean.
|
||||
* @param bean the bean
|
||||
* @return the boolean
|
||||
*/
|
||||
public static boolean isProxy(Object bean) {
|
||||
if (bean == null) {
|
||||
return false;
|
||||
}
|
||||
// check dubbo proxy ?
|
||||
return DubboUtil.isDubboProxyName(bean.getClass().getName())
|
||||
|| (Proxy.class.isAssignableFrom(bean.getClass()) || AopUtils.isAopProxy(bean));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the target class , get the interface of its agent if it is a Proxy
|
||||
* @param proxy the proxy
|
||||
* @return target interface
|
||||
* @throws Exception the exception
|
||||
*/
|
||||
public static Class<?> getTargetInterface(Object proxy) throws Exception {
|
||||
if (proxy == null) {
|
||||
throw new IllegalArgumentException("proxy can not be null");
|
||||
}
|
||||
|
||||
// jdk proxy
|
||||
if (Proxy.class.isAssignableFrom(proxy.getClass())) {
|
||||
Proxy p = (Proxy) proxy;
|
||||
return p.getClass().getInterfaces()[0];
|
||||
}
|
||||
|
||||
return getTargetClass(proxy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the class type of the proxy target object, if hadn't a target object, return
|
||||
* the interface of the proxy
|
||||
* @param proxy the proxy
|
||||
* @return target interface
|
||||
* @throws Exception the exception
|
||||
*/
|
||||
protected static Class<?> getTargetClass(Object proxy) throws Exception {
|
||||
if (proxy == null) {
|
||||
throw new IllegalArgumentException("proxy can not be null");
|
||||
}
|
||||
// not proxy
|
||||
if (!AopUtils.isAopProxy(proxy)) {
|
||||
return proxy.getClass();
|
||||
}
|
||||
AdvisedSupport advisedSupport = getAdvisedSupport(proxy);
|
||||
Object target = advisedSupport.getTargetSource().getTarget();
|
||||
/*
|
||||
* the Proxy of sofa:reference has no target
|
||||
*/
|
||||
if (target == null) {
|
||||
if (CollectionUtils.isNotEmpty(advisedSupport.getProxiedInterfaces())) {
|
||||
return advisedSupport.getProxiedInterfaces()[0];
|
||||
}
|
||||
else {
|
||||
return proxy.getClass();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return getTargetClass(target);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the all interfaces of bean, if the bean is null, then return empty array
|
||||
* @param bean the bean
|
||||
* @return target interface
|
||||
*/
|
||||
public static Class<?>[] getAllInterfaces(Object bean) {
|
||||
Set<Class<?>> interfaces = new HashSet<>();
|
||||
if (bean != null) {
|
||||
Class<?> clazz = bean.getClass();
|
||||
while (!Object.class.getName().equalsIgnoreCase(clazz.getName())) {
|
||||
Class<?>[] clazzInterfaces = clazz.getInterfaces();
|
||||
interfaces.addAll(Arrays.asList(clazzInterfaces));
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
}
|
||||
return interfaces.toArray(new Class[0]);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
com.pig4cloud.pigx.common.seata.config.SeataAutoConfiguration
|
||||
@@ -0,0 +1,56 @@
|
||||
seata:
|
||||
enabled: true
|
||||
tx-service-group: pigx_tx_group # 事务群组(可以每个应用独立取名,也可以使用相同的名字)
|
||||
client:
|
||||
rm-report-success-enable: true
|
||||
rm-table-meta-check-enable: false # 自动刷新缓存中的表结构(默认false)
|
||||
rm-report-retry-count: 5 # 一阶段结果上报TC重试次数(默认5)
|
||||
rm-async-commit-buffer-limit: 10000 # 异步提交缓存队列长度(默认10000)
|
||||
rm:
|
||||
lock:
|
||||
lock-retry-internal: 10 # 校验或占用全局锁重试间隔(默认10ms)
|
||||
lock-retry-times: 30 # 校验或占用全局锁重试次数(默认30)
|
||||
lock-retry-policy-branch-rollback-on-conflict: true # 分支事务与其它全局回滚事务冲突时锁策略(优先释放本地锁让回滚成功)
|
||||
tm-commit-retry-count: 3 # 一阶段全局提交结果上报TC重试次数(默认1次,建议大于1)
|
||||
tm-rollback-retry-count: 3 # 一阶段全局回滚结果上报TC重试次数(默认1次,建议大于1)
|
||||
undo:
|
||||
data-validation: true # 二阶段回滚镜像校验(默认true开启)
|
||||
log-serialization: kryo # undo序列化方式(默认jackson 不支持 LocalDateTime)
|
||||
log-table: undo_log # 自定义undo表名(默认undo_log)
|
||||
log:
|
||||
exceptionRate: 100 # 日志异常输出概率(默认100)
|
||||
support:
|
||||
spring:
|
||||
datasource-autoproxy: true
|
||||
service:
|
||||
vgroup-mapping:
|
||||
pigx_tx_group: default # TC 集群(必须与seata-server保持一致)
|
||||
enable-degrade: false # 降级开关
|
||||
disable-global-transaction: false # 禁用全局事务(默认false)
|
||||
grouplist:
|
||||
default: pigx-seata:8091
|
||||
transport:
|
||||
shutdown:
|
||||
wait: 3
|
||||
thread-factory:
|
||||
boss-thread-prefix: NettyBoss
|
||||
worker-thread-prefix: NettyServerNIOWorker
|
||||
server-executor-thread-prefix: NettyServerBizHandler
|
||||
share-boss-worker: false
|
||||
client-selector-thread-prefix: NettyClientSelector
|
||||
client-selector-thread-size: 1
|
||||
client-worker-thread-prefix: NettyClientWorkerThread
|
||||
type: TCP
|
||||
server: NIO
|
||||
heartbeat: true
|
||||
serialization: seata
|
||||
compressor: none
|
||||
enable-client-batch-send-request: true # 客户端事务消息请求是否批量合并发送(默认true)
|
||||
registry:
|
||||
file:
|
||||
name: file.conf
|
||||
type: file
|
||||
config:
|
||||
file:
|
||||
name: file.conf
|
||||
type: file
|
||||
Reference in New Issue
Block a user