oracle事务_笔记7:分布式事务
分布式事务
Oracle有很多很好的特性,其中之一就是能够透明地处理分布式事务。在一个事务的范围内,可以更新多个不同数据库中的数据。提交时,要么提交所有实例中的更新,要么一个都不提交(它们都会回滚)。为此,我不需要另外编写任何代码;只是“提交”就行了。
Oracle中分布式事务的关键是数据库链接(database link)。数据库链接是一个数据库对象,描述了如何从实例登录到另一个实例。一旦建立了一个数据库链接,访问远程对象就很简单了,如下:
select * from T@another_database;
这会从数据库链接ANOTHER_DATABASE所定义数据库实例的表T中选择。一般地,你会创建表T的一个视图(或一个同义词),来“隐藏”T是一个远程表的事实。例如,可以发出以下命令,然后就可以像访问本地表一样地访问T了:
create synonym T for T@another_database;
既然建立了这个数据库链接,而且能读取一些表,还能够修改这些表(假设有适当的权限)。现在执行一个分布式事务与执行一个本地事务没什么两样。
update local_table set x=5;
update remote_table@another_database set y=10;
commit;
Oracle会完成所有数据库中的提交,或者都不提交。它使用了一个2PC(two-phase commit protocol,二段提交协议)来做到这一点。2PC是一个分布式协议,如果一个修改影响到多个不同的数据库,2PC允许原子性地提交这个修改。它会在提交之前尽可能地关闭分布式失败窗口。在多个数据库之间的一个2PC事务中,其中一个数据库(通常是客户最初登录的那个数据库)会成为分布式事务的协调器。这个站点会询问其他站点是否已经准备好提交。实际上,这个站点会转向其他站点,问它们是否准备就绪。其他的每个站点会报告它的“就绪状态”(YES或NO)。如果只有一个站点投票NO,整个事务就会回滚。如果所有站点都投票YES,站点协调器会广播一条消息,使每个站点上的提交成为永久性的。
2PC会限制可能出现严重错误的窗口(时间窗)。在2PC上“投票”之前,任何分布式错误都会导致所有站点回滚。对于事务的结果来说,这里不存在疑义。在提交或回滚之后,分布式事务的结果同样没有疑义。只有一个非常短的时间窗除外,此时协调器要收集投票结果,只有在这个时候如果失败,结果可能有疑义。
对于分布式事务中能做的事情,还存在一些限制,这些限制是合理的。其中重要的限制如下所述。
.不能在数据库链接上发出COMMIT。也就是说,不能发出COMMIT@remote_site。只能从发起事务的那个站点提交。
.不能在数据库链接上完成DDL。这是上一个问题带来的直接结果。DDL会提交,而除了发起事务的站点外,不能从任何站点提交,所以不能在数据库链接上完成DDL。
.不能在数据库链接上发出SAVEPOINT。简单地说,不能在数据库链接上发出任务事务控制语句。所有事务控制都由最初打开数据库链接的会话继承得来;对于事务中的分布式实例,不能有不同的事务控制。
尽管数据库链接上缺乏事务控制,但是这是合理的,因为只有发起事务的站点才有参与事务的所有站点的一个列表。
可以设置站点的COMMIT_POINT_STRENGTH,从而改变具体的提交站点。COMMIT_POINT_STRENGTH会为分布式事务中的服务器关联一个相对的重要性级别。服务器越重要,它就越有可能协调这个分布式事务。如果需要在生产主机和测试主机之间完成一个分布式事务,你可能希望这样做。由于事务协调器对于事务的结果绝对不会有疑义,最好是由生产主机协调分布式事务。你并不关心测试主机是否有一些打开的事务和锁定的资源。但是如果生产系统上有这种情况,你肯定会很关心。
不能在数据库链接上执行DDL。首先,DDL很少见。只会在安装或升级期间执行一次DDL。生产系统不会执行DDL。其次,要在数据库链接上执行DDL也是有办法的,只是采用另一种方式。可以使用作业队列工具DBMS_JOB,或者在Oracle Database 10g中可以调度工具包DBMS_SCHEDULER。你不用试图在链接上执行DDL,而是可以使用链接来调度一个远程作业,一旦提交就执行这个远程作业。采用这种方式,作业在远程主机上运行,这不是一个分布式事务,可以执行DDL。
实际上,Oracle Replication Service(复制服务)就采用这种方法执行分布式DDL来实现模式复制。
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5244.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
