✨ pigx-common-seata模块

This commit is contained in:
付绪壮 committed 2022-04-06 15:51:51 +08:00
1 parent 46dd2b9742
commit 166eec29ec
8 files changed
+366

No files matched your search

+13
View File
@@ -36,6 +36,8 @@
<xxl.job.version>2.3.0</xxl.job.version>
<aliyun.version>3.0.52.ALL</aliyun.version>
<aws.version>1.11.543</aws.version>
<seata.version>1.4.2</seata.version>
<asm.version>7.1</asm.version>
<log4j2.version>2.17.1</log4j2.version>
<javaformat.plugin.version>0.0.23</javaformat.plugin.version>
<docker.plugin.version>0.33.0</docker.plugin.version>
@@ -144,6 +146,17 @@
<artifactId>pigx-upms-api</artifactId>
<version>${pigx.version}</version>
</dependency>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
<version>${asm.version}</version>
</dependency>
<!-- seata kryo 序列化-->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-serializer-kryo</artifactId>
<version>${seata.version}</version>
</dependency>
<!--mybatis plus extension,包含了mybatis plus core-->
<dependency>
<groupId>com.baomidou</groupId>
@@ -0,0 +1,44 @@
package com.pig4cloud.pigx.common.core.factory;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.lang.Nullable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
/**
* @author lengleng
* @date 2022/3/29
* <p>
* 读取自定义 yaml 文件工厂类
*/
public class YamlPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
Properties propertiesFromYaml = loadYamlIntoProperties(resource);
String sourceName = name != null ? name : resource.getResource().getFilename();
return new PropertiesPropertySource(sourceName, propertiesFromYaml);
}
private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException {
try {
YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
factory.setResources(resource.getResource());
factory.afterPropertiesSet();
return factory.getObject();
}
catch (IllegalStateException e) {
Throwable cause = e.getCause();
if (cause instanceof FileNotFoundException)
throw (FileNotFoundException) e.getCause();
throw e;
}
}
}
+51
View File
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
~
-->
<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>4.3.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
@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,5 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
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: pig-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
+1
View File
@@ -45,6 +45,7 @@
<module>pigx-common-job</module>
<module>pigx-common-log</module>
<module>pigx-common-oss</module>
<module>pigx-common-seata</module>
<module>pigx-common-security</module>
<module>pigx-common-sentinel</module>
<module>pigx-common-sequence</module>