关于分布式事务

时间:2022-01-12 11:13:47

昨天的一顿午饭,让我想起了企业分布式开发的真正需求,特别是适合我们的在window平台下的分布式开发。

在java的世界中,企业开发相对简单。因为有一大堆的企业级中间件供你使用,而且也会有相对的很多标准供你参考。但是在window平台下,好像没有java世界那么繁华。那么企业的分布式开发到底最需要什么呢?

相信很多人都已经拜读了j2ee without ejb,有幸我和其中的一个译者对于“分布式开发”进行过交流。结果我们取得了一致的观点:在分布式系统中,最重要的还是分布式事务。

那么现在就留下了最后一个问题:怎么解决分布式事务?

在java世界中,首选的是jta,那么在window平台下,早期是通过com组件来完成,从framework2.0开始,提供了 system.transaction这个命名空间来提供功能,其实此命名空间走的是ms-dtc,其实还是com组件。而且,从使用msdtc的反应来看,真是一点都不名不虚传啊,完全符合“MSDTC七宗罪”的论断。

那么我们应该怎么解决分布式事务呢?首先来看看spring.net给我们提供的方案,除了上面的msdtc方式,spring.net还有一种居于adonet技术,使用aop,proxy实现的分布式事务控制方式。首先,我们在需要配置实用事务的方法,然后在程序运行时,使用aop方式截断方法的执行,在方法执行前开启事务,方法执行完成后提交事务,就是这么简单。但是使用aop技术,完全依靠reflecting,proxy技术实现,所以性能有所损耗。有兴趣的朋友可以看看spring.net的源代码。

以前我还使用过一种“硬编码”的方式解决分布式事务问题,中心思想就是在需要操作的数据库中分别开启事务,然后执行操作,最后判断执行的结果采取是提交事务还是回滚事务;如果在任何一个数据库事务中发生异常,即所有的事务全部回滚。相对于jta,msdtc这种重量级的分布式事务解决方案而言,这种方式相对轻便,对系统要求较低,性能也可以接受,唯一可能出现隐患的地方就是执行数据库操作的步骤,但是这和担心只是在完全使用“范式”来设计的数据库中才可能发生,所以综合下来,这个方案还是可以接受的。(我们可以通过自己提供ormapping的方式来配置对象之间的关系,从而解决这个操作顺序问题)。