Hibernate事务未启动异常排查:同步事务API问题咨询
问题分析与解决方案:手动事务与Spring声明式事务冲突
你遇到的这个错误,核心原因是同时混用了Spring的声明式事务(@Transactional注解)和Hibernate手动事务管理,两者的事务控制逻辑发生了冲突。
为什么会报错?
@Transactional注解的本质是让Spring帮你自动接管事务的全生命周期:从方法开始时自动开启事务,执行完方法逻辑后自动提交(如果没有异常)或者回滚(如果抛出异常)。- 但你在方法内部又手动调用了
currentSession.beginTransaction()和transaction.commit()——这相当于在Spring已经启动的事务之外,又手动启动并提交了一个事务。当Spring后续尝试提交它自己管理的事务时,发现事务状态已经被手动操作打乱,就会抛出Transaction not successfully started的错误。
为啥功能还能正常实现?
这要归功于你加的@Synchronized注解:它保证了所有请求串行执行,即使事务管理层面有冲突,第一个请求的手动提交已经完成了数据更新,第二个请求等待后拿到的也是更新后的数据,所以功能看起来是正常的,但事务层面的异常是实打实的问题。
修正方案
推荐两种修正方式,优先选第一种:
方案1:保留@Transactional,移除手动事务代码
让Spring全权管理事务,去掉手动开启和提交事务的代码:
@Synchronized @Transactional(readOnly = false, isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class) myApi() { def currentSession = sessionFactory.currentSession String query = """update table set column = :value""" Map params = [value: "value"] currentSession.doWork(new Work() { public void execute(Connection connection) { Sql sql = new Sql(connection) // 注意:Sql.executeUpdate的参数顺序是先SQL语句,再参数,你之前写反了 int updateCount = sql.executeUpdate(query, params) } }) // 无需手动commit,Spring会自动处理事务提交/回滚 }
这里还要提醒你:你之前的sql.executeUpdate(params, query)参数顺序是错误的,Sql类的executeUpdate方法通常是先传入SQL语句,再传入参数映射,调整后能避免潜在的SQL执行错误。
方案2:移除@Transactional,完全手动管理事务(不推荐)
如果一定要手动控制事务,就去掉@Transactional注解,自己处理事务的开启、提交和回滚:
@Synchronized myApi() { def currentSession = sessionFactory.currentSession def transaction = null try { transaction = currentSession.beginTransaction() String query = """update table set column = :value""" Map params = [value: "value"] currentSession.doWork(new Work() { public void execute(Connection connection) { Sql sql = new Sql(connection) int updateCount = sql.executeUpdate(query, params) } }) transaction.commit() } catch (Exception e) { // 异常时手动回滚事务 if (transaction != null && transaction.isActive()) { transaction.rollback() } throw e // 抛出异常让上层处理 } }
总结
优先选择方案1,利用Spring的声明式事务可以避免手动操作事务带来的各种潜在问题,同时@Synchronized已经保证了请求的串行执行,完全满足你“同一时间仅执行一个请求,后续请求使用更新后的数据”的需求。
内容的提问来源于stack exchange,提问作者Uday Reddy
相关产品推荐
相关产品推荐

