mybatis使用TypeHandler PGobject不当导致postgresql jsonb字段异常赋值
近期发现生产上部分表jsonb字段出现赋值异常,像是被异常设置了其他表的jsonb字段的值,经过排查,发现之前在网上参考的TypeHandler有问题导致的,以下为错误示例。
@MappedTypes({Object.class})
public class JsonbTypeHandler extends BaseTypeHandler<Object> {
//重点!!! PGobject非线程安全
private static final PGobject PG_OBJECT = new PGobject();
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType)
throws SQLException {
if (Objects.nonNull(ps)) {
PG_OBJECT.setType("jsonb");
PG_OBJECT.setValue(parameter.toString());
ps.setObject(i, PG_OBJECT);
}
}
// 其余代码略...
}
其中由于PGobject对象是非线程安全的,导致在并发下jsonb字段更新的值,可能由另一个jsonb的值覆盖,导致数据的异常更新。
知道问题,剩下的就很好解决了,通过每次在方法内new一个新的PGobject对象使用,或者使用ThreadLocal.withInitial的给每个线程创建一个对应的PGobject实例,但是经过查看源码,PGobject的结构比较简单,创建不会有很大的开销,一般来说直接new应该就可以。