xa分布式事务处理.docx
《xa分布式事务处理.docx》由会员分享,可在线阅读,更多相关《xa分布式事务处理.docx(30页珍藏版)》请在冰豆网上搜索。
xa分布式事务处理
XA分布式事务处理2008-12-1116:
12
在谈到XA规范之前,必须首先了解分布式事务处理(DistributedTransactionProcessing,DTP)的概念。
Transaction,即事务,又称之为交易,指一个程序或程序段,在一个或多个资源如数据库或文件上为完成某些功能的执行过程的集合。
分布式事务处理是指一个事务可能涉及多个数据库操作,分布式事务处理的关键是必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚)。
X/Open组织(即现在的OpenGroup)定义了分布式事务处理模型。
X/OpenDTP模型(1994)包括应用程序(AP)、事务管理器(TM)、资源管理器(RM)、通信资源管理器(CRM)四部分。
一般,常见的事务管理器(TM)是交易中间件,常见的资源管理器(RM)是数据库,常见的通信资源管理器(CRM)是消息中间件。
通常把一个数据库内部的事务处理,如对多个表的操作,作为本地事务看待。
数据库的事务处理对象是本地事务,而分布式事务处理的对象是全局事务。
所谓全局事务,是指分布式事务处理环境中,多个数据库可能需要共同完成一个工作,这个工作即是一个全局事务,例如,一个事务中可能更新几个不同的数据库。
对数据库的操作发生在系统的各处但必须全部被提交或回滚。
此时一个数据库对自己内部所做操作的提交不仅依赖本身操作是否成功,还要依赖与全局事务相关的其它数据库的操作是否成功,如果任一数据库的任一操作失败,则参与此事务的所有数据库所做的所有操作都必须回滚。
一般情况下,某一数据库无法知道其它数据库在做什么,因此,在一个DTP环境中,交易中间件是必需的,由它通知和协调相关数据库的提交或回滚。
而一个数据库只将其自己所做的操作(可恢复)影射到全局事务中。
--------------------------------------------------------------------------------
XA就是X/OpenDTP定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。
XA接口函数由数据库厂商提供。
XA与两阶段提交协议
--------------------------------------------------------------------------------
通常情况下,交易中间件与数据库通过XA接口规范,使用两阶段提交来完成一个全局事务,XA规范的基础是两阶段提交协议。
在第一阶段,交易中间件请求所有相关数据库准备提交(预提交)各自的事务分支,以确认是否所有相关数据库都可以提交各自的事务分支。
当某一数据库收到预提交后,如果可以提交属于自己的事务分支,则将自己在该事务分支中所做的操作固定记录下来,并给交易中间件一个同意提交的应答,此时数据库将不能再在该事务分支中加入任何操作,但此时数据库并没有真正提交该事务,数据库对共享资源的操作还未释放(处于上锁状态)。
如果由于某种原因数据库无法提交属于自己的事务分支,它将回滚自己的所有操作,释放对共享资源上的锁,并返回给交易中间件失败应答。
在第二阶段,交易中间件审查所有数据库返回的预提交结果,如所有数据库都可以提交,交易中间件将要求所有数据库做正式提交,这样该全局事务被提交。
而如果有任一数据库预提交返回失败,交易中间件将要求所有其它数据库回滚其操作,这样该全局事务被回滚。
以一个全局事务为例,AP首先通知交易中间件开始一个全局事务,交易中间件通过XA接口函数通知数据库开始事务,然后AP可以对数据库管理的资源进行操作,数据库系统记录事务对本地资源的所有操作。
操作完成后交易中间件通过XA接口函数通知数据库操作完成。
交易中间件负责记录AP操作过哪些数据库(事务分支)。
AP根据情况通知交易中间件提交该全局事务,交易中间件会通过XA接口函数要求各个数据库做预提交,所有数据库返回成功后要求各个数据库做正式提交,此时一笔全局事务结束。
--------------------------------------------------------------------------------
XA规范对应用来说,最大好处在于事务的完整性由交易中间件和数据库通过XA接口控制,AP只需要关注与数据库的应用逻辑的处理,而无需过多关心事务的完整性,应用设计开发会简化很多。
--------------------------------------------------------------------------------
具体来说,如果没有交易中间件,应用系统需要在程序内部直接通知数据库开始、结束和提交事务,当出现异常情况时必须由专门的程序对数据库进行反向操作才能完成回滚。
如果是有很多事务分支的全局事务,回滚时情况将变得异常复杂。
而使用XA接口,则全局事务的提交是由交易中间件控制,应用程序只需通知交易中间件提交或回滚事务,就可以控制整个事务(可能涉及多个异地的数据库)的全部提交或回滚,应用程序完全不用考虑冲正逻辑。
在一个涉及多个数据库的全局事务中,为保证全局事务的完整性,由交易中间件控制数据库做两阶段提交是必要的。
但典型的两阶段提交,对数据库来说事务从开始到结束(提交或回滚)时间相对较长,在事务处理期间数据库使用的资源(如逻辑日志、各种锁),直到事务结束时才会释放。
因此,使用典型的两阶段提交相对来说会占用更多的资源,在网络条件不是很好,如低速网、网络颠簸频繁,情况会更为严重。
当一个全局事务只涉及一个数据库时,有一种优化方式,即一阶段提交。
当AP通知交易中间件提交事务时,交易中间件直接要求数据库提交事务,省去两阶段提交中的第一阶段,可以缩短处理一个事务的时间,以提高事务处理的效率。
作为两阶段提交的一种特例,与两阶段一样,一阶段提交也是标准的。
XA分布式事务处理
在谈到XA规范之前,必须首先了解分布式事务处理(DistributedTransactionProcessing,DTP)的概念。
Transaction,即事务,又称之为交易,指一个程序或程序段,在一个或多个资源如数据库或文件上为完成某些功能的执行过程的集合。
分布式事务处理是指一个事务可能涉及多个数据库操作,分布式事务处理的关键是必须有一种方法可以知道事务在任何地方所做的所有动作,提交或回滚事务的决定必须产生统一的结果(全部提交或全部回滚)。
X/Open组织(即现在的OpenGroup)定义了分布式事务处理模型。
X/OpenDTP模型(1994)包括应用程序(AP)、事务管理器(TM)、资源管理器(RM)、通信资源管理器(CRM)四部分。
一般,常见的事务管理器(TM)是交易中间件,常见的资源管理器(RM)是数据库,常见的通信资源管理器(CRM)是消息中间件。
通常把一个数据库内部的事务处理,如对多个表的操作,作为本地事务看待。
数据库的事务处理对象是本地事务,而分布式事务处理的对象是全局事务。
所谓全局事务,是指分布式事务处理环境中,多个数据库可能需要共同完成一个工作,这个工作即是一个全局事务,例如,一个事务中可能更新几个不同的数据库。
对数据库的操作发生在系统的各处但必须全部被提交或回滚。
此时一个数据库对自己内部所做操作的提交不仅依赖本身操作是否成功,还要依赖与全局事务相关的其它数据库的操作是否成功,如果任一数据库的任一操作失败,则参与此事务的所有数据库所做的所有操作都必须回滚。
一般情况下,某一数据库无法知道其它数据库在做什么,因此,在一个DTP环境中,交易中间件是必需的,由它通知和协调相关数据库的提交或回滚。
而一个数据库只将其自己所做的操作(可恢复)影射到全局事务中。
XA就是X/OpenDTP定义的交易中间件与数据库之间的接口规范(即接口函数),交易中间件用它来通知数据库事务的开始、结束以及提交、回滚等。
XA接口函数由数据库厂商提供。
XA与两阶段提交协议
通常情况下,交易中间件与数据库通过XA接口规范,使用两阶段提交来完成一个全局事务,XA规范的基础是两阶段提交协议。
在第一阶段,交易中间件请求所有相关数据库准备提交(预提交)各自的事务分支,以确认是否所有相关数据库都可以提交各自的事务分支。
当某一数据库收到预提交后,如果可以提交属于自己的事务分支,则将自己在该事务分支中所做的操作固定记录下来,并给交易中间件一个同意提交的应答,此时数据库将不能再在该事务分支中加入任何操作,但此时数据库并没有真正提交该事务,数据库对共享资源的操作还未释放(处于上锁状态)。
如果由于某种原因数据库无法提交属于自己的事务分支,它将回滚自己的所有操作,释放对共享资源上的锁,并返回给交易中间件失败应答。
在第二阶段,交易中间件审查所有数据库返回的预提交结果,如所有数据库都可以提交,交易中间件将要求所有数据库做正式提交,这样该全局事务被提交。
而如果有任一数据库预提交返回失败,交易中间件将要求所有其它数据库回滚其操作,这样该全局事务被回滚。
以一个全局事务为例,AP首先通知交易中间件开始一个全局事务,交易中间件通过XA接口函数通知数据库开始事务,然后AP可以对数据库管理的资源进行操作,数据库系统记录事务对本地资源的所有操作。
操作完成后交易中间件通过XA接口函数通知数据库操作完成。
交易中间件负责记录AP操作过哪些数据库(事务分支)。
AP根据情况通知交易中间件提交该全局事务,交易中间件会通过XA接口函数要求各个数据库做预提交,所有数据库返回成功后要求各个数据库做正式提交,此时一笔全局事务结束。
XA规范对应用来说,最大好处在于事务的完整性由交易中间件和数据库通过XA接口控制,AP只需要关注与数据库的应用逻辑的处理,而无需过多关心事务的完整性,应用设计开发会简化很多。
具体来说,如果没有交易中间件,应用系统需要在程序内部直接通知数据库开始、结束和提交事务,当出现异常情况时必须由专门的程序对数据库进行反向操作才能完成回滚。
如果是有很多事务分支的全局事务,回滚时情况将变得异常复杂。
而使用XA接口,则全局事务的提交是由交易中间件控制,应用程序只需通知交易中间件提交或回滚事务,就可以控制整个事务(可能涉及多个异地的数据库)的全部提交或回滚,应用程序完全不用考虑冲正逻辑。
在一个涉及多个数据库的全局事务中,为保证全局事务的完整性,由交易中间件控制数据库做两阶段提交是必要的。
但典型的两阶段提交,对数据库来说事务从开始到结束(提交或回滚)时间相对较长,在事务处理期间数据库使用的资源(如逻辑日志、各种锁),直到事务结束时才会释放。
因此,使用典型的两阶段提交相对来说会占用更多的资源,在网络条件不是很好,如低速网、网络颠簸频繁,情况会更为严重。
当一个全局事务只涉及一个数据库时,有一种优化方式,即一阶段提交。
当AP通知交易中间件提交事务时,交易中间件直接要求数据库提交事务,省去两阶段提交中的第一阶段,可以缩短处理一个事务的时间,以提高事务处理的效率。
作为两阶段提交的一种特例,与两阶段一样,一阶段提交也是标准的。
动态编译JAVA程序|BEATuxedo2009-04-02
oracle分布式事务总结
oracle分布式事务总结(转)
2008-09-1817:
47
基本概念
LocalCoordinator:
在分布事务中,必须参考其它节点上的数据才能完成自己这部分操作的站点。
GlobalCoordinator:
分布事务的发起者,负责协调这个分布事务。
CommitPointSite:
在分布事务中,首先执行COMMIT或ROLLBACK操作的站点。
一般情况下,应该把存储关键数据的站点作为CommitPointSite。
因为CommitPointSite和其它站点不一样,从来不会进入prepared状态,所以不会存在IN-DOUBT事务。
可以设置初始化参数COMMIT_POINT_STRENGTH,在分布式事务中,会根据这个值的大小来确定CommitPointSite,分布事物的状态信息也存在该数据库中。
一般将关键的数据库作为commitpointsite,commit_point_strength值较高的数据库为commitpointsite,在分布事物中最先提交
分布式提交的3个阶段
分布事物的两阶段提交分三个过程:
1.准备阶段(PREPAREPHASE)
·本地数据库GlobalCoordinator向其它数据库发出COMMIT通知
·比较所有数据库的SCN号,将最高的SCN号作为分布事物的全局SCN号
·所有数据库写在线日志
·对分布事物修改的表加分布锁,防止被读写
·各数据库向GlobalCoordinator发出已经准备好的通知
所有参与分布事物的数据库必须经过上述准备,才能进入下一阶段。
2.提交阶段(COMMITPHASE)
·本地数据库GlobalCoordinator通知commitpointsite首先提交。
commitpointsite提交后,释放其占有的资源,通知GlobalCoordinator完成提交
·本地数据库GlobalCoordinator通知其它数据库提交
·提交节点在日志中追加一条信息,表示分布事物已经完成提交,并通知GlobalCoordinator。
此时所有数据库的数据保持了一致性。
3.注销阶段(FORGETPHASE)
·本地数据库GlobalCoordinator通知commitpointsite所有数据库已经完成提交
·commitpointsite清除分布事物的记录和状态信息,并通知GlobalCoordinator
·GlobalCoordinator清除本地分布事物的记录和状态信息
此时分布事物的两阶段提交全部完成。
如果两阶段提交完成之前,数据库或网络出现异常,应用就会报错,分布事物处于IN_DOUBT状态。
一旦数据库或网络恢复正常,系统(RECOPROCESS)会自动处理IN_DOUBT状态的分布事物。
有些情况需要管理员手工处理IN_DOUBT状态的分布事物:
·IN_DOUBT状态的分布事物,将关键表锁住,造成应用不能正常工作
两个重要的视图
DBA_2PC_PENDING:
列出所有的悬而未决的事务﹐此视图在末填入悬而未决的事务之前是空的﹐解决这后也被清空。
LOCAL_TRAN_ID
本地事务标识﹐格式为integer.integer.ingeger。
当一个连接的local_tran_id和global_tran_id相同时﹐那么该节点是该事务的全局协调器。
GLOBAL_TRAN_ID
全局事务标识,格式为﹕global_db_name.db_hex_id.local_tran_id,其中db_hex_id是用来标识数据库八字符的十六进制数﹐公共事各id在分布式事务的每个节点都是相同的。
“YES”意味着一部分事务已经在一个节点上提交﹐而在另一个节点上被回滚。
TRAN_COMMENT
事务的注释﹐或者如果使用了事务命名﹐当事各被提交时﹐事务的名字就会出现在此处
已提交的事务的全局提交数
DBA_2PC_PENDING的STATE列的说明
Connecting
通常情况下﹐只有全局协调器和本地协调器才使用这个条目﹐节点在能够决定它是否能够准备好之前﹐要收集来自于其它数据库服务的信息。
节点已准好﹐可能或者也可能没有将已准备好的消息通知本地协调器﹐但此时﹐该节点还没有接收到提交的请求﹐仍保持着准许备好的状态﹐控制着提交事务所必需的任何本地资源。
节点(任何类型)已经提交了事务﹐但该事务所包含的其它节点可能并没有提交﹐也就是该事务在一个个或多个其它节点上仍然是悬而未决。
Forcedcommit
DBA进行判断后﹐可以强行提交未决的事务﹐如果一个事务由DBA在本地节点进行手动提交时﹐产生此项目
Forcedabor(rollback)
DBA进行判断后﹐可以强行回滚未决的事务﹐如果一个事务由DBA在本地节点进行手动回滚时﹐产生此项目
DBA_2PC_NEIGHBORS:
列出所有获得的(从远程客户)和送出的(给远程服务器)悬而未决的事务﹐也表示该本地节点是不是事务的提交点站点。
LOCAL_TRAN_ID
对获得事务来说指本地节点信息的客户数据库的名称﹔对送出的事务来说指用于访问远程服务器上信息的数据库链接的名称
DBuser_owner
对获得事务来说指远程数据库链接用于连接的本地账户﹔对于送出事务来说指该数据库链接的拥有者。
INTERFACE
‘C’代表提交信息﹐’N’表示已准备好状态的一条消息或是一条请求只读提交的请求。
当’IN_OUT’为OUT时﹐’C’表示该连接的远程的站点是提交点站点,并且知道是提交还是中断。
’N’表示本地节点正在通知远程节点﹐说它已准备好。
当’IN_OUT’为IN时﹐‘C’表示本地节点或送出的远程的一个数据库是提交点站点﹐’N’表示本地节点正在通知远程节点﹐说它已准备好。
处理悬挂事务的一般步骤
1、检查alert文件,发现类似下面error:
ORA-1591"lockheldbyin-doubtdistributedtransaction%s"
ORA-2062"distributedrecoveryreceiveddbidx,expectedy"
ORA-2068"followingsevereerrorfrom%s%s"
2、确认网络是否正常、dblink是否valid、v$dblink和gv$dblink中查询当前是否在使用分布式事务。
3、查询视图dba_2pc_pending,查询悬挂事务信息:
SELECTLOCAL_TRAN_ID,GLOBAL_TRAN_ID,STATE,MIXED,HOST,COMMIT#
FROMDBA_2PC_PENDING
WHERELOCAL_TRAN_ID='?
?
.';
如果没有记录,说明RECO进程已经自动处理了该事务。
4、在所有节点上查询视图dba_2pc_neighbors
5、得到所有节点的COMMIT_POINT_STRENGTH值,值最大的为commitpointsite,即最早提交的点,如果悬挂事务发生在commitpointsite,则它的state决定了整个分布式事务的状态。
悬挂事务是否应该commitforce或者是rollbackforce,由此节点决定。
6、检查dba_2pc_pending的state列,如果是commited,意味着本地数据库提交已经成功。
其他节点需要根据本地事务号和最大的commit#进行强制提交。
用法如下:
SVRMGR>COMMITFORCE'yourlocaltransactionIDonthisnode','highestSCNfromalreadycommittedsite';
SVRMGR>COMMITFORCE'1.13.5197','88123887';
7、如果commitpointsite的state为commited外的其他状态,则表明commitpointsite没有提交成功,分布式事务需要强制回滚。
这里不再需要所有节点的最大commit#。
用法如下:
SVRMGR>ROLLBACKFORCE'yourlocaltransactionIDonthisnode';
SVRMGR>ROLLBACKFORCE'1.13.5197';
8、清除dba_2pc_pending和dba_2pc_neighbers的相关记录。
一般分布式事务自动恢复后,视图内容会自动清除,如果是手工提交的事务,则需要用dbms_transaction包手工清除,清除规则如下表所示:
确定何时能使用DBMS_TRANSACTION
Collecting
Purge_lost_db_entry(只有当自动回复不能解决事务时)
Committed
Committed
Committed
Purge_lost_db_entry(只有当自动回复不能解决事务时)
Forced
Commit
Committed
Purge_lost_db_entry(只有当自动回复不能解决事务时)
Forcedrollback
Purge_lost_db_entry(只有当自动回复不能解决事务时)
Forcedcommit
Committed
手动删除不一致性﹐然后使用purge_mixed
Forcedrollback
手动删除不一致性﹐然后使用purge_mixed
测试记录
¡设置db1的commit_point_strength为1,db2的commit_point_strength为2,db2为commitpointsite。
¡db1、db2上执行100次insert循环,每次循环用分布式事务插入db1和db2中的测试表。
中间rebootdb2服务器。
此时db1对测试表的查询出现以下错误:
SQL>selectcount
(1)fromtemp.my_table;
selectcount
(1)fromtemp.my_table
*
ERRORatline1:
ORA-01591:
lockheldbyin-doubtdistributedtransaction7.30.7415
[oracle@db2bdump]$tail-falert_ntespay.log
TueMar414:
14:
282008
DISTRIBTRAN1234.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
islocaltran7.30.7415(hex=07.1e.1cf7)
insertpendingpreparedtran,scn=934346533(hex=0.37b0ff25)
db1中分布式事务相关的2个视图内容如下:
selecta.*fromdba_2pc_pendingawhereLOCAL_TRAN_ID='7.30.7415';
LOCAL_TRAN_IDGLOBAL_TRAN_IDSTATEMIXEDADVICETRAN_COMMENTFAIL_TIMEFORCE_TIMERETRY_TIMEOS_USEROS_TERMINALHOSTDB_USERCOMMIT#
17.30.74154660.4F000000000000000000000000000000000000000000000000000000