记一次solon使用jackson序列化踩坑

前景提要

事情起因是 业务需求 需要返回值Date类型有的时间是带时分秒有的需要年月日,使用yml进行配置的话是全局。因为使用的是jackson。第一时间想到的是 @JsonFormat 注解。接下来一系列流程,写上去、重启、测试、发现没有生效。就看着文档使用bean的方式自定义JacksonRenderFactoryJacksonActionExecutor 不用yml配置文件全局定义方式了。使用 @JsonSerialize 自定义序列化格式化时间。发现好使!至此,问题开始爆出来了。

某次启动项目,发现自定义的序列化时间全部失效了。所有接口返回的时间全部是jackson默认的时间戳格式。重启就好了。但是这是个问题,不一定什么时候就爆炸了。

带着问题在群里问了@西东 大佬(solon作者),被大佬带着一步步分析最终解决问题。下边讲讲思路。

分析问题

  1. 推翻原来写的全部东西。正常来说全局配置的优先级应该低于注解的优先级。最初使用yml配置的时候使用注解思路肯定是没有问题。
  2. 重启之后又好了80% 是因为引入了两个 json 的序列化插件。
  3. 问题出现的时候,在bean自定义序列化的地方打了一次断点,并没有进入bean,说明序列化被别的插件给顶掉了。

解决问题

  1. 解决问题的最快方式就是摒弃无用的代码,只看关于这次问题的代码。就是写demo。新建个demo项目。引入jackson。发现好好的。也没问题。重启几次之后,复现了不生效问题。

根据大佬的指点,发现solon-web中有snack序列化插件。如图:
在这里插入图片描述
移除此序列化组件
在这里插入图片描述
至此,@JsonFormat注解才可以正常使用。
注:solon框架中,@JsonFormat注解2.9.0及以上版本才兼容。

  1. demo项目可以使用了。项目中总也可以了吧。在项目中也排除了snack3的序列化组件,发现项目起不起来了。

在这里插入图片描述
检查依赖,发现很多依赖都依赖于jackson,版本也有冲突,

在这里插入图片描述
挨个排除!解决问题

总结:遇到问题写demo复现问题,才能更好的解决问题

<think>我们正在讨论Solon 3.6版本中的事务使用方法。根据引用[1]中提到的Solon Data事务的使用方法,并结合用户之前的问题,我们可以总结如下: ### 一、Solon 3.6事务使用方法 #### 1. 启用事务管理 在Solon中,事务管理是通过拦截器机制实现的。首先,需要确保事务开关已打开。在插件启动时,通过判断`solon.data.trace.enable`配置来决定是否启用事务拦截器。 在Solon 3.6中,可以通过以下方式配置事务开关: ```yaml # application.yml solon: data: trace: enable: true # 开启事务支持 ``` 在插件启动类中,添加事务拦截器: ```java public class XPluginImp implements Plugin { @Override public void start(AppContext context) { // 判断事务是否启用,如果启用则添加事务拦截器 if (Solon.app().enableTransaction()) { context.beanInterceptorAdd(Tran.class, new TranInterceptor(), 120); } } } ``` #### 2. 使用`@Tran`注解 在需要事务管理的方法上添加`@Tran`注解。Solon提供了`@Tran`注解来声明事务,该注解可以配置事务的属性,如传播行为、隔离级别、只读属性等。 示例: ```java @Service public class UserService { @Inject UserMapper userMapper; // 引用[1]中提到的MyBatis Mapper @Tran // 在方法上添加@Tran注解,开启事务 public void updateUser(User user) { userMapper.update(user); // 更新用户信息 // 其他数据库操作 } } ``` #### 3. 注解参数配置 `@Tran`注解支持多个参数,用于配置事务属性: - `propagation`: 事务传播行为(例如`Propagation.REQUIRED`,默认值) - `isolation`: 事务隔离级别(例如`Isolation.DEFAULT`,默认使用数据库默认隔离级别) - `readOnly`: 是否只读事务(默认`false`) - `rollbackFor`: 指定触发回滚的异常类型(默认为`Throwable`,即所有异常都回滚) 示例:配置隔离级别和传播行为 ```java @Tran(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRES_NEW) public void updateWithNewTransaction(User user) { // ... } ``` #### 4. 异常处理 默认情况下,如果方法抛出任何异常(`Throwable`或其子类),事务将回滚。可以通过`rollbackFor`和`noRollbackFor`属性自定义回滚规则。 示例:指定特定异常回滚 ```java @Tran(rollbackFor = SQLException.class) public void updateUser(User user) throws SQLException { // 如果发生SQLException,则回滚;其他异常不会触发回滚 } ``` ### 二、整合MyBatis使用事务 在Solon中整合MyBatis(如引用[1]所示)时,事务的使用方式与上述一致。只需要确保: 1. 配置了数据源(如HikariCP)。 2. 添加了`mybatis-solon-plugin`依赖。 事务拦截器会自动管理MyBatis的SqlSession事务。 ### 三、注意事项 1. **事务方法调用**:在同一类中,一个没有`@Tran`注解的方法调用另一个有`@Tran`注解的方法,事务不会生效。这是因为事务基于AOP代理,自调用不会经过代理对象。解决方案:将事务方法移到另一个Bean中,或者通过AopContext获取当前代理对象再调用(Solon支持类似Spring的AopContext)。 2. **多数据源事务**:Solon支持多数据源事务,但需要配置多个事务管理器(通常每个数据源一个)。在`@Tran`注解中可以通过`name`属性指定事务管理器名称(对应数据源名称)。 ### 四、分布式事务 对于分布式事务,Solon可以通过整合Seata等框架实现。但需要额外配置Seata的相关组件,这超出了本次问题的范围。 ### 总结 在Solon 3.6中使用事务的步骤: 1. 开启事务配置(`solon.data.trace.enable=true`)。 2. 在需要事务的方法上添加`@Tran`注解。 3. 根据需要配置注解参数(隔离级别、传播行为等)。 以上内容参考了Solon官方文档和引用[1][^1]。 §§相关问题§§ 1. Solon中如何配置多数据源事务? 2. Solon的事务传播行为有哪些?与Spring的事务传播行为有何异同? 3. 在Solon中,如何实现声明式事务的回滚规则自定义? 4. Solon的事务管理如何整合分布式事务框架(如Seata)? </think>### Solon 3.6 事务使用详解 基于引用[1][^1]和Solon官方实践,以下是Solon 3.6版本的事务使用方法及最佳实践: --- #### 一、基础配置 1. **启用事务支持** 在 `app.yml` 中配置: ```yaml solon: data: trace: enable: true # 必须开启事务支持[^1] ``` 2. **添加依赖** 根据ORM框架选择对应插件(以MyBatis为例): ```xml <dependency> <groupId>org.noear</groupId> <artifactId>mybatis-solon-plugin</artifactId> <version>3.5.2</version> <!-- 兼容3.6+ --> </dependency> ``` --- #### 二、声明式事务 在方法上添加 `@Tran` 注解: ```java @Service public class OrderService { @Inject OrderDao orderDao; @Inject UserDao userDao; // 基本事务 @Tran public void createOrder(Order order) { orderDao.insert(order); userDao.updateCredit(order.userId, -order.amount); } // 自定义事务属性 @Tran( propagation = Propagation.REQUIRES_NEW, // 新事务 isolation = Isolation.READ_COMMITTED, // 读已提交 rollbackFor = SQLException.class // 指定回滚异常 ) public void updateOrder(Order order) { // 业务逻辑 } } ``` --- #### 三、关键特性 1. **传播行为** | 传播类型 | 说明 | |-------------------|-----------------------------| | `REQUIRED`(默认) | 当前有事务则加入,无则新建 | | `REQUIRES_NEW` | 始终新建独立事务 | | `NESTED` | 嵌套事务(Savepoint机制) | 2. **混合ORM支持** 支持同时操作MyBatis和Hibernate(引用[4][^4]): ```java @Tran public void hybridOperation() { hibernateRepo.save(entity); // Hibernate操作 mybatisMapper.update(data); // MyBatis操作 } ``` --- #### 四、注意事项 1. **自调用失效** 同类中非代理方法调用 `@Tran` 方法无效: ```java public void process() { createOrder(order); // ❌ 事务不生效 } ``` 2. **多数据源事务** 需指定事务管理器名称: ```java @Tran(name = "db2") // 对应多数据源配置 public void multiDbOperation() { ... } ``` --- ### 最佳实践 1. **事务边界** - 在Service层声明事务,避免在DAO层使用 - 单个事务中数据库操作不超过5个 2. **异常处理** ```java @Tran(rollbackFor = {BusinessException.class, SQLException.class}) public void safeOperation() { try { // 业务代码 } catch (DataAccessException e) { throw new BusinessException(e); // 触发回滚 } } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值