- 场景一:
单一线程多次进入子事务发生死锁 - 问题:
线上问题发生了死锁,但通过死锁日志发现一直在等待查询结果。我们使用的数据库是PGsql,默认的隔离级别是“读已提交”,按理来说查询不会加锁,导致一度被带偏。 - 原因:
内层事务执行完update后提交事务,但由于内层事务被外层事务包裹着,所以实际上update对应修改的数据行级锁未释放。当第二次进入内层事务进行update时,由于未能获取数据行级锁则一直等待。
第一个内层事务持有锁,直到外层事务全部执行完才进行释放,外层事务等待第二个方法执行完才能往下走,第二个内层事务又一直在等待行级锁。所以导致死锁发生。
- 扩展:
嵌套事务导致的问题:
1、内层事务回滚,只能回滚全部事务,无法控制单一事务回滚
2、内层事务提交后,回滚外层事务,也会把内层提交了的事务一起回滚
3、因为2的原因,只要整个事务不完全提交,日志空间都无法被释放