Closed Stone-afk closed 1 year ago
我仔细想了一下,的确是改成表维度更好。但是我们还是可以考虑优化的。
也就是说,如果在表维度的时候,将所有的语句放进去一个事务里面,比每个语句都单独执行性能会更加好。
for _, db := range dstDBs {
tx := db.Begin()
for _, tab := range tabs {
// 执行表上面的每一个语句
tx.Exec()
}
db.Commit
}
之所以会说性能好很多,主要很对的是数据库的持久化机制。比如说在 MySQL 的 innoDB 引擎下,默认配置是 redo log 每个 commit 就刷新到磁盘。所以我们这里合并为一个事务之后,那么 redo log 就可以只刷新一次,那么相比多次刷新,省去了系统调用和寻址之类的问题(虽然本身就是 WAL 也很快)。
另外一方面,这种优化可以确保,至少在某个数据库上,操作是保证 ACID 的。也就是说,虽然跨库保证不了 ACID,但是跨表但是不跨库是可以的。
这里忽略了 ds 只考虑了 db 吧,还有是不是要考虑长事务带来的影响
比如 造成 大量的阻塞和锁超时,主从延迟啥的
只考虑 DB,数据库是做不到跨 DB 事务的吧?暂时保持表维度吧,长事务我倒是没有想到的。不过这个要支持,需要先支持了分布式事务。
“只考虑 DB,数据库是做不到跨 DB 事务的吧?” 我的意思是你的描述里忽略了 ds
支持了分布式事务后,其实用户也可以自己手动开事务
我的意思是说,在支持了分布式事务之后,只要我们在操作 Insert 的时候启用那个延迟事务,就可以了。剩余的事情,事务会帮我们解决
这下子可怕了,我们要全部改成 DB 维度了。
目前来看,在真实的执行场景下做不到按照 DB 维度来发送请求。 有两个问题:
1、尝试使用 multiStatements=true 选项的时候,依旧会出错; 2、即便可以使用 multiStatements,也难以教会用户在这里必须要指定 multiStatements,而且 db 那块代码的设计还要在原来的基础上做改动,目前也不想我们自己拼接一个
所以改成一个表一个