如何将数据库操作中的事务代码抽取为独立方法?
抽取重复数据库事务代码的实现方案
你可以通过函数式接口封装业务逻辑的方式,将重复的事务管理代码(开启事务、提交、回滚、异常处理)抽取为通用方法,同时兼容有返回值和无返回值的数据库操作。
第一步:定义通用事务处理方法
创建两个通用方法,分别对应有返回值和无返回值的业务场景:
// 处理带返回值的数据库操作 private <T> T executeWithResult(Supplier<T> businessAction) { Session session = null; try { session = sessionFactory.getCurrentSession(); session.beginTransaction(); // 执行具体业务逻辑并获取返回值 T result = businessAction.get(); session.getTransaction().commit(); return result; } catch (Exception ex) { // 异常时回滚事务(仅当事务仍活跃时) if (session != null && session.getTransaction().isActive()) { session.getTransaction().rollback(); } ex.printStackTrace(); // 根据业务场景返回默认值,这里针对List返回空列表,其他场景可调整 return businessAction.get() instanceof List ? (T) List.of() : null; } } // 处理无返回值的数据库操作 private void executeWithoutResult(Consumer<Session> businessAction) { Session session = null; try { session = sessionFactory.getCurrentSession(); session.beginTransaction(); // 传入Session执行具体业务逻辑 businessAction.accept(session); session.getTransaction().commit(); } catch (Exception ex) { if (session != null && session.getTransaction().isActive()) { session.getTransaction().rollback(); } ex.printStackTrace(); } }
第二步:改造原有数据库操作方法
将原来的getAllCars、updateCar、deleteCar方法简化,调用通用事务方法封装业务逻辑:
1. 查询方法(带返回值)
public List<Car> getAllCars() { return executeWithResult(() -> session.createQuery("from Car", Car.class).getResultList() ); }
2. 更新方法(无返回值)
public void updateCar(Car car, Long id) { executeWithoutResult(session -> { Car updatableCar = session.get(Car.class, id); if (updatableCar == null) { throw new NoSuchElementException("No such car in table"); } UpdateField updateField = new UpdateField(); updateField.updFields(updatableCar, car); session.persist(updatableCar); }); }
3. 删除方法(无返回值)
public void deleteCar(Long id) { executeWithoutResult(session -> { Car deletableCar = session.get(Car.class, id); if (deletableCar == null) { throw new NoSuchElementException("No such car in table"); } session.remove(deletableCar); }); }
核心思路说明
Supplier<T>:用于封装有返回值的业务逻辑,通过get()方法获取执行结果,适配查询类操作。Consumer<Session>:用于封装无返回值的业务逻辑,通过accept(session)方法传入Session执行操作,适配更新、删除类操作。- 通用方法统一处理事务的生命周期和异常,所有业务方法仅需关注具体的数据库操作逻辑,彻底消除重复代码。
内容的提问来源于stack exchange,提问作者Ruslan
相关产品推荐
相关产品推荐

