Best Efforts 1PC 跨库事务

Best Efforts 1PC 跨库事务

一、背景介绍

分布式事务主要解决两种事务问题,一个是跨库事务,另一个是跨服务事务;跨库是指在一个事务里面包含多个数据源的数据库操作。跨服务是一个事务中包行多个不同的应用系统的服务。best efforts 1pc 主要解决的是一个应用服务中跨多个数据源的数据一致性问题,不能解决跨服务的一致性问题。跨服务的数据一致性需要通过两阶段、三阶段或者其他分布式方案来保证。

二、什么是Best Efforts 1PC模式

首先事务的实现方式是通过动态代理的方式对原方法进行增强,在原方法执行前关闭自动提交,原方法执行后调用commit方法显示的进行提交。详细可以参考着文章 https://blog.csdn.net/khuangliang/article/details/108458906

每个事务Transaction必须在指定的数据源DataSource下进行操作来获取数据库连接Connection,对于多个数据源的数据库操作在一个事务中进行的时候就需要对应多个数据的Transactions,对于这些Transactions不能串行的一个一个操作完后提交,需要在数据库操作完后统一全部提交。Best Efforts 1PC就是通过这种方式实现的,应此它只涉及到一个提交的阶段,不需要额外的协调者,执行效率高。

insert() 方法是一个事务操作
insert() {
	// 插入数据库1
	insertDb1(); 对应数据库操作分解---db1[begin; insert; commit]
	// 插入数据库2
	insertDb2(); 对应数据库操作分解----db2[begin; insert; commit]
}

我们看个实例,在insert方法中涉及两个数据库的操作insertDb1和insertDb2,要保证insert方法的事务特性就不能在insertDb1入库了之后,然后在insertDb2入库这样串行的去操作,因为如果insertDb2失败了而insertDb1事务成功完成了那么insertDb1回滚不了。所以需要按照db1,db2[begin; insert;]—>[db2 commit, db1 commit] 这种方式去执行,打乱原有的操作顺序。通过这种后面的操作先提交前面的操作后提交的方式来确保insertDb2发生异常的化能正常回滚insertDb1操作。

三、Best Efforts 1PC适用场景和优劣

Best Efforts 1PC由于只有一个commit提交阶段因此执行效率高,非常适合那种分库sharding的对性能要求高的应用场景,但是对于应用突发宕机的这种情况还是可能会出现不一致的情况,例如上例中db2 commit成功后应用宕机了,db1 commit失败同样会造成数据的不一致性,这种场景就需要业务系统通过一定的方式来达到数据的最终一致性。

你可能感兴趣的:(mybatis,mysql,数据库,spring,分布式,java)