【问题】
这段代码在调试过程中遇到一个出乎意料的问题:在数据存储过程中,出了data too long的问题,但是try/catch中却没有捕获到。代码如下:
进行debug的时候发现,代码会顺利地将try中的代码执行完,而后return。之后在TransactionAspectSupport的commitTransactionAfterReturning方法执行时在控制台打印了sql,并抛出了Data too long:
-------------------------------------------------------------------------------------------
【修复】
经过网上的一番查找和讨论,最终确定问题有两种解决方案:
1.去掉@Transactional。经过测试,去掉注解确实是有效的。从代码本身来看,没有多个步骤的事务操作,所以这个注解也是没必要的,正好去除掉也避免了这个bug,加了注解后这里就会使用一个代理来执行逻辑,性能上肯定比不上直接执行逻辑的。
2.这里不执行数据库层面的操作,可能是Hibernate的一种优化,即缓存。我们使用saveAndFlush,可以让其在此处执行到db层面,捕获到这个异常。
在搜索的过程中,发现很多人都遇到过Hibernate的save不生效的问题。其实这个时候只要往Hibernate的save缓存的思路上靠,基本上十之八九就能解决。
-------------------------------------------------------------------------------------------
【原因不明】
在重新搭建了一套Hibernate+Spring+@Transactional的环境代码,试图还原这个现象时,我发现没有出现图1代码中的问题。一方面,对于Hibernate的优化机制不清楚,另一方面对于@Transactional的具体流程和逻辑也不清楚,所以想探寻原因可以说基本上无从下手。所以说,业务逻辑的代码都能写,但是懂得原理我们才能在除了问题之后迅速定位并找到真正有效的解决方案。这也为自己提了个醒,对于自己日常使用的框架,还是要把原理弄明白,但这也需要一点点积累,后面还是要多写一些原理方向的blog。