✅代码中使用长事务,会带来哪些问题?

典型回答

长事务通常是指在数据库系统中,运行时间较长、执行时间跨度较大的事务。我们应该尽可能的避免长事务,主要由以下几个原因:

1、事务的执行时间长,就会持续占用数据库的连接。因为数据库的连接数是有固定限制的,被长时间占用就会使得其他的事务无法获得连接,导致数据库的整体吞吐量下降。

2、事务中如果加了锁,那么锁会一直在事务中被持有,那么就会导致锁冲突多,导致数据库吞吐量下降,甚至可能会导致大量的死锁问题。

在MySQL的官网中,提到了3个和长事务有关的问题:

17229271036572.jpg

3、InnoDB使用MVCC来实现并发控制,长事务会导致旧版本的数据持续存在,影响数据库的清理操作(如Purging),从而影响整体性能。详见:

✅undolog会一直存在吗?什么时候删除?

4、当在长事务中修改或删除行时,如果其他使用 READ COMMITTED和 REPEATABLE READ隔离级别的事务读取这些相同的行,则它们必须做更多的工作来重建旧数据。(这里主要指的是undolog的生成)

5、当一个长事务修改一个表时,可能会导致其他事务对该表的查询不使用覆盖索引技术。

详见:


✅二级索引在索引覆盖时如何使用MVCC?

所以我们应该尽可能的拆分长事务,在一个事务中,不要干太多的事儿,尤其是一些和数据库操作无关的内存计算、远程调用等等。以及一些普通的查询,也可以现在事务外查询,然后在更新的时候再开启事务。

所以,尽可能的使用编程式事务来代替声明式事务,因为声明式事务的粒度都是整个方法级别的,和容易导致长事务。

原文: https://www.yuque.com/hollis666/xkm7k3/odhck7oslpx0mra0