1, 前面一篇的文章介绍了TransactionTemplate的基本使用方法.
同事在其基础上又做了一层封装,这样更贴合本公司的业务与规范.
2, 首先定义了两个接口:
ServiceTemplate ----> 对TransactionTemplate进行了封装
1 public interface ServiceTemplate { 2 3 /** 4 * <pre> 无事务模板执行业务处理 5 * 1. 异常捕获,及分类处理 6 * 2. 业务日志记录 7 * </pre> 8 * 9 * @param <T> 10 * @param clazz 返回对象 11 * @param action 业务操作回调的接口 12 * @return 服务返回对象 13 */ 14 <T> T executeWithoutTransaction(Class<? extends Result> clazz, ServiceCallback action); 15 16 /** 17 * <pre> 支持本地事务模板执行业务处理 18 * 1. 本地事务封装 19 * 2. 异常捕获,及分类处理 20 * 3. 业务日志记录 21 * </pre> 22 * 23 * @param <T> 24 * @param clazz 返回对象 25 * @param action 业务操作回调的接口 26 * @return 服务返回对象 27 */ 28 <T> T execute(Class<? extends Result> clazz, ServiceCallback action); 29 30 }
ServiceCallback ----> 对TransactionCallBack进行了封装
1 public interface ServiceCallback { 2 /** 3 * <pre> 校验 4 * 对于校验不通过,异常驱动返回 5 * </pre> 6 */ 7 void doLock(); 8 9 /** 10 * <pre> 校验 11 * 对于校验不通过,异常驱动返回 12 * </pre> 13 */ 14 void check(); 15 16 /** 17 * <pre> 执行业务逻辑 18 * </pre> 19 * @return 20 */ 21 Result executeService(); 22 }
ServiceTemplate的具体实现如下:
1 public class ServiceTemplateImpl implements ServiceTemplate { 2 3 /** 事务模板 */ 4 @Autowired 5 private TransactionTemplate transactionTemplate; 6 7 @Override 8 public <T> T executeWithoutTransaction(Class<? extends Result> clazz, 9 ServiceCallback action) { 10 Result result = null; 11 try { 12 // 执行校验 13 action.check(); 14 //锁操作 15 action.doLock(); 16 17 // 执行处理逻辑 18 result = action.executeService(); 19 //可以对结果进行初步校验TODO 20 21 22 } catch (自定义异常 e) { 23 //打日志TODO 24 return (T) result; 25 26 } catch (Throwable e2) { 27 //打日志TODO 28 return (T) result; 29 } 30 31 return (T) result; 32 } 33 34 @Override 35 @SuppressWarnings("unchecked") 36 public <T> T execute(final Class<? extends Result> clazz, final ServiceCallback action) { 37 T acResult = (T) transactionTemplate.execute(new TransactionCallback() { 38 /** 39 * @see org.springframework.transaction.support.TransactionCallback#doInTransaction(org.springframework.transaction.TransactionStatus) 40 */ 41 public Object doInTransaction(TransactionStatus status) { 42 43 Result result = null; 44 45 try { 46 47 result = clazz.newInstance(); 48 // 执行校验逻辑 49 action.check(); 50 51 //锁操作 52 action.doLock(); 53 54 // 执行处理逻辑 55 result = action.executeService(); 56 // 返回值异常处理 57 if (result == null || !(result instanceof BaseResult)) { 58 throw new 自定义异常; 59 } 60 61 } catch (自定义异常 e) { 62 // 业务异常捕获, 回滚, 打日志TODO 63 64 status.setRollbackOnly(); 65 66 return result; 67 } catch (Throwable e2) { 68 // 系统异常捕获, 回滚, 打日志TODO 69 status.setRollbackOnly(); 70 return result; 71 } 72 return result; 73 } 74 }); 75 return acResult; 76 } 77 78 }
3, 在业务方法中使用ServiceTemplate, 通过构建ServiceCallBack匿名内部类的方式, 传递具体的业务代码:
1 public Result update(final BaseOrder baseOrder) { 2 return serviceTemplate.execute(BooleanResult.class, new ServiceCallback() { 3 @Override 4 public void doLock() { 5 //进行锁操作 6 } 7 8 @Override 9 public void check() { 10 //进行校验 11 } 12 13 @Override 14 public Result executeService() { 15 Result result = new Result(); 16 //具体的业务代码 17 return result; 18 } 19 }); 20 }
注意: 如果是不需要加事务的方法, 如查询 ,那么调用serviceTemplate的executeWithoutTransaction即可