seata 踩坑记录
文章目录
1.seata1.4.2 版本 有个bug,客户端启动时候影响了spring security oauth2的bean初始化
原因:seata1.4.2中io.seata.spring.utilsProxyUtils#findTargetSpringClass中获取代理对象的方法targetSource.getTargetClass()引起的。
在1.4.1 之前,对于TargetSource这个对象, 认为就是静态对象,所以直接取的targetSource.getTargetClass()
在1.4.2版本,又完全认为是一个动态对象,而这里的问题就是获取一个被代理的动态对象时,实际上是不能获取这个对象的, 只能获取这个对象的类型.
// 省略无关代码段
@Configuration
public class OAuth2ClientConfiguration {
// spring 要创建这个对象, 创建后被seata的SpringProxyUtils感知
// 实际上这是一个动态对象,是不能在启动阶段拿这个值的
// 这里定义的方式是: ScopedProxyFactoryBean->SimpleBeanTargetSource->当前对象
@Bean
@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)
protected AccessTokenRequest accessTokenRequest(@Value("#{request.parameterMap}")
Map<String, String[]> parameters, @Value("#{request.getAttribute('currentUri')}")
String currentUri) {
}
@Configuration
protected static class OAuth2ClientContextConfiguration {
// 1. spring 要注入这个对象
@Resource
@Qualifier("accessTokenRequest")
private AccessTokenRequest accessTokenRequest;
}
}
//1.4.2 代码
public static Class<?> findTargetClass(Object proxy) throws Exception {
if (proxy == null) {
return null;
}
if (AopUtils.isAopProxy(proxy) && proxy instanceof Advised) {
Object targetObject = ((Advised) proxy).getTargetSource().getTarget();
return findTargetClass(targetObject);
}
return proxy.getClass();
}
改正:或者切换版本1.4.1,或者等待seata官网出1.4.3版本
public static Class<?> findTargetClass(Object proxy) throws Exception {
if (proxy == null) {
return null;
}
// 把这里加一个条件判断,静态就可以获取对象并且递归获取具体的类型。
// 动态的话,是万万不能直接获取对象的
if (AopUtils.isAopProxy(proxy) && proxy instanceof Advised) {
final TargetSource targetSource = ((Advised) proxy).getTargetSource();
if (!targetSource.isStatic()) {
return targetSource.getTargetClass();
}
// 支持静态域的层次情况
return findTargetClass(targetSource.getTarget());
}
return proxy.getClass();
}
2. seata切换序列化方式jackson->kryo,缺少类:java.lang.NoClassDefFoundError:de/javakaffee/kryoserializers/CurrencySerializer
解决方法: 导入jar包
<dependency>
<groupId>de.javakaffee</groupId>
<artifactId>kryo-serializers</artifactId>
<version>0.36</version>
</dependency>
3. 执行分支事务提交时候报错: get table meta error:Failed to fetch schema of 表名
java.sql.SQLException: Failed to fetch schema of 表名
分析: 这是因为代理的表结构没有创建主键,造成原因
解决: 添加表主键