xa分布式事务处理_第1页
xa分布式事务处理_第2页
xa分布式事务处理_第3页
xa分布式事务处理_第4页
xa分布式事务处理_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

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-02oracle分布式事务总结oracle分布式事务总结(转)2008-09-1817:47基本概念LocalCoordinator:在分布事务中,必须参考其它节点上的数据才能完成自己这部分操作的站点。GlobalCoordinator:分布事务的发起者,负责协调这个分布事务。CommitPointSite:在分布事务中,首先执行COMMIT或ROLLBACK操作的站点。一般情况下,应该把存储关键数据的站点作为CommitPointSite0因为CommitPointSite和其它站点不一样,从来不会进入prepared状态,所以不会存在IN-DOUBT事务。可以设置初始化参数COMMIT_POINT_STRENGTH,在分布式事务中,会根据这个值的大小来确定CommitPointSite,分布事物的状态信息也存在该数据库中。一般将关键的数据库作为commitpointsite,commit_point_strength值较高的数据库为commitpointsite,在分布事物中最先提交分布式提交的3个阶段分布事物的两阶段提交分三个过程:准备阶段(PREPAREPHASE)•本地数据库GlobalCoordinator向其它数据库发出COMMIT通知•比较所有数据库的SCN号,将最高的SCN号作为分布事物的全局SCN号•所有数据库写在线日志•对分布事物修改的表加分布锁,防止被读写•各数据库向GlobalCoordinator发出已经准备好的通知所有参与分布事物的数据库必须经过上述准备,才能进入下一阶段。提交阶段(COMMITPHASE)•本地数据库GlobalCoordinator通知commitpointsite首先提交。commitpointsite提交后,释放其占有的资源,通知GlobalCoordinator完成提交•本地数据库GlobalCoordinator通知其它数据库提交•提交节点在日志中追加一条信息,表示分布事物已经完成提交,并通知GlobalCoordinator。此时所有数据库的数据保持了一致性。注销阶段(FORGETPHASE)•本地数据库GlobalCoordinator通知commitpointsite所有数据库已经完成提交commitpointsite清除分布事物的记录和状态信息,并通知GlobalCoordinatorGlobalCoordinator清除本地分布事物的记录和状态信息此时分布事物的两阶段提交全部完成。如果两阶段提交完成之前,数据库或网络出现异常,应用就会报错,分布事物处于IN_DOUBT状态。一旦数据库或网络恢复正常,系统(RECOPROCESS)会自动处理IN_DOUBT状态的分布事物。有些情况需要管理员手工处理IN_DOUBT状态的分布事物:-IN_DOUBT状态的分布事物,将关键表锁住,造成应用不能正常工作两个重要的视图DBA_2PC_PENDING:列出所有的悬而未决的事务,此视图在末填入悬而未决的事务之前是空的,解决这后也被清空。LOCAL_TRAN_ID本地事务标识,格式为eger.ingege。当一个连接的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通常情况下,只有全局协调器和本地协调器才使用这个条目,节点在能够决定它是否能够准备好之前,要收集来自于其它数据库服务的信息。节点已准好,可能或者也可能没有将已准备好的消息通知本地协调器,但此时,该节点还没有接收到提交的请求,仍保持着准许备好的状态,控制着提交事务所必需的任何本地资源。节点(任何类型)已经提交了事务,但该事务所包含的其它节点可能并没有提交,也就是该事务在一个个或多个其它节点上仍然是悬而未决。ForcedcommitDBA进行判断后,可以强行提交未决的事务,如果一个事务由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_PENDINGWHERELOCAL_TRAN_ID='??.';如果没有记录,说明RECO进程已经自动处理了该事务。4、在所有节点上查询视图dba_2pc_neighbors5、得到所有节点的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_TRANSACTIONCollectingPurge_lost_db_entry(只有当自动回复不能解决事务时)CommittedCommittedCommittedPurge_lost_db_entry(只有当自动回复不能解决事务时)ForcedCommitCommittedPurge_lost_db_entry(只有当自动回复不能解决事务时)ForcedrollbackPurge_lost_db_entry(只有当自动回复不能解决事务时)ForcedcommitCommitted手动删除不一致性,然后使用purge_mixedForcedrollback手动删除不一致性,然后使用purge_mixed测试记录i设置db1的commit_point_strength为1,db2的commit_point_strength为2,

db2为commitpointsite。idbl、db2上执行100次insert循环,每次循环用分布式事务插入db1和db2中的测试表。中间rebootdb2服务器。此时dbl对测试表的查询出现以下错误:SQL>selectcount(l)fromtemp.my_table;selectcount(1)fromtemp.my_table*ERRORatline1:ORA-01591:lockheldbyin-doubtdistributedtransaction7.30.7415[oracle@db2bdump]$tail-falert_ntespay.logTueMar414:14:282008TRANDISTRIB1234.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000TRANislocaltran7.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_IDTRAN_COMMENTFAIL_TIMEOS_TERMINALHOSTGLOBAL_TRAN_IDSTATEMIXEDADVICEFORCE_TIMELOCAL_TRAN_IDTRAN_COMMENTFAIL_TIMEOS_TERMINALHOST17.30.74154660.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000preparedno2008-3-414:14:282008-3-414:22:56zhenxingzhaiZHAIZHENXINGNETEASE\ZHAIZHENXING934346533其中,state有以下几种状态:Collecting,prepared,committed,forcedcommit,orforcedrollbackmixed表示是否部分提交,部分回滚advice:Cforcommit,Rforrollback,elseNULLselecta.*fromdba_2pc_neighborsawhereLOCAL_TRAN_ID='7.30.7415';LOCAL_TRAN_IDIN_OUTDATABASEDBUSER_OWNERINTERFACEDBIDSESS#BRANCH17.30.7415inNULLTEMPNjavaxa_orcl101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000此视图说明了数据源1的输入连接信息。因为数据源2不是通过dblink连接的,以此没有出现它的记录。idb2重启后查询my_tab:SQL>selectcount(1)frommy_tab;COUNT(1)75i因为db2中dba_2pc_pending和dba_2pc_neighbers中没有记录,并且db2为commitpointsite,没有记录意味着没有进行任何操作,所以db1应该和db2一样,进行强制rollbackoSQL>conn/assysdbaConnected.SQL>rollbackforce'7.30.7415';Rollbackcomplete.SQL>selectcount(12)fromtemp.my_table;COUNT(12)75db1的alert日志中显示了可疑事务的回滚过程:TueMar415:14:312008DISTRIBTRAN1234.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000islocaltran7.30.7415(hex=07.1e.1cf7)changependingpreparedtran,scn=934346533(hex=0.37b0ff25)topendingforcedrollbacktran,scn=934346533(hex=0.37b0ff25)i回滚后,两个视图中的状态更改为如下:selecta.*fromdba_2pc_pendingawhereLOCAL_TRAN_ID='9.33.5992';LOCAL_TRAN_IDGLOBAL_TRAN_IDSTATEMIXEDADVICETRAN_COMMENTFAIL_TIMEFORCE_TIMERETRY_TIMEOS_USEROS_TERMINALHOSTDB_USERCOMMIT#17.30.74154660.4F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000forcedrollbackno2008-3-414:14:282008-3-415:14:312008-3-415:20:07zhenxingzhaiZHAIZHENXINGNETEASE\ZHAIZHENXING934346533selecta.*fromdba_2pc_neighborsawhereLOCAL_TRAN_ID='9.33.5992';LOCAL_TRAN_IDIN_OUTDATABASEDBUSER_OWNERINTERFACEDBIDSESS#BRANCH17.30.7415inNULLTEMPNjavaxa_orcl101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000i去除dba_2pc_pending和dba_2pc_neighbors中的记录:Disable分布式恢复SQL>ALTERSYSTEMDISABLEDISTRIBUTEDRECOVERY;Systemaltered.Puege(清空)in-doubttransactionentry:SQL>execDBMS_TRANSACTION.PURGE_LOST_DB_ENTRY('7.30.7415');PL/SQLmit;然后enable分布式恢复:SQL>ALTERSYSTEMENABLEDISTRIBUTEDRECOVERY;分布式事务相关资料Note:1012842.102Note:100664.1Note:274321.1Note:126069.1事务处理的nuts和boltsDr.SubrahmanyamAllamaraju©SubrahmanyamAllamaraju1999.Allrightsreserved.Thisdocumentisprotectedbycopyright.Nopartofthisdocumentmaybereproducedinanyformwithoutpriorwrittenconsentoftheauthor.Thisdocumentisforelectronicdistributiononly.Alltrademarksacknowledged.翻译:寒蝉退士译者的声明版权声明中声明了“未经版权持有者的书面允许不得以任何形式复制本文内容,本文档只以电子版的形式发布”,很显然,版权声明没有限制对电子版的翻译和在网络上传播。译者对译文不做任何形式的担保。译者对译文不拥有任何权利并且不负担任何义务。任何人在对译文进行任何处置(包括但不限于复制、传播)之前,应当认真阅读版权声明,译者对其他人的行为不负任何责任。译序:译者添加的图6引自介绍ORBacusOTS的网页。译者乃一介草莽,译文中难免存在疏失错讹,祈望仁者指正。原文:/articles/transactions/NutsAndBoltsOfTP.html介绍事务管理是对企业应用最紧要的要求之一。在贸易、金融和电子商业领域中,多数大的企业应用依赖于递送它们的商务的事务处理功能。鉴于当今商务对灵活性的要求,在建造、部署和维护企业级别的分布式应用中,事务处理占据的是其中最复杂的部分之一。本文把以下内容介绍给读者:•什么是事务?什么是ACID?•建造一个事务应用的要点是什么?事务管理中间件为什么很重要?•事务处理应用的典型的体系是怎样的?体系中的各种构件的职责是什么?•事务处理系统涉及哪些概念?•事务管理领域中有哪些标准和技术?本文不特定于任何产品,力图在描述各种要点和概念时保持普遍性。本文不打算比较各种事务处理的技术/标准,只是提供对此的一个讨论。什么是事务?为了完成对数据的操作,企业应用经常要求并发访问在多个构件之间共享的数据。这些应用在下列条件下应该维护数据的完整性(由应用的商务规则来定义):•分布式访问一个单独的数据资源,以及•从一个单独的应用构件访问分布式资源。在这种情况,可能要求在(分布式)资源上的一组操作被当作一个工作单元(unit)。在一个工作单元中,操作的所有部分一起成功或失败并恢复。在下面的情况下这个问题更加复杂:•通过一组分布式的、访问多个资源的数据的构件实现一个工作单元,和/或•部分操作是被顺序执行的或在要求协调和/或同步的并行线程中。在所有情况下,都要求应用维护一个工作单元的成功或失败。在失败的情况下,所有资源要把数据状态返回到以前的状态(比如说,工作单元开始前的状态)。事务的概念和和事务管理器(或者一个事务处理服务)在一个工作单元中的维护数据完整性,这就简化了这样的企业级别分布式应用的构造。一个事务是有下列属性的一个工作单元:•原子性(ATOMICITY):一个事务要被完全的无二义性的做完或撤消。在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到以前的状态。•一致性(CONSISTENCY):一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致状态转换到另一个一致状态。举个例子,在关系数据库的情况下,一个一致的事务将保护定义在数据上的所有完整性约束。•隔离性(ISOLATION):在同一个环境中可能有多个事务并发执行,而每个事务都应表现为独立执行。串行的执行一系列事务的效果应该同于并发的执行它们。这要求两件事:o在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。o两个并发的事务应该不能操作同一项数据。数据库管理系统通常使用锁来实现这个特征。•持久性(DURABILITY):一个被完成的事务的效果应该是持久的。这些属性叫做ACID属性,担保一个事务是永远不会不完整,数据永远不会不一致,并发事务是独立的,一个事务的效果是持久的。关于在分布式系统什么能出错的简要的一个描述,请参见在事务处理系统中的容错和恢复。建造事务性应用的要点为了引出在建造事务性应用中涉及的要点,考虑一个定单获得和定单处理应用,它的体系在图1中展示:图1:定单获得和定单处理应用这个应用由两个客户构件组成,分别实现定单获得和定单处理操作。这两个操作构成了一个工作或事务单元。分别基于产品,定单,库存清单和货运信息。在这个图中,点断尖头指示的只读的数据访问,而连续尖头指示指示的是修改数据的事务性操作。下面是在这个应用中的事务性操作:•生成定单,•更新库存,•生成货运记录,并•更新定单状态。当作为一个事务来实现这些操作时,应致力于下述要点:应用应当与事务性操作和被操作的数据库保持联系。所以应用应该为所有事务定义一个上下文来包含上述四个操作。因为定单获得和定单处理事务分布于两个构件之上,事务上下文应该是全局的,并通过协议的转换、被从第一个构件传播到第二个。当事务发生期间,应用应当监控事务的状态。为了维护事务的原子性,应用构件和/或数据库服务器、应当实现一种机制,在这种机制下对数据库的更改可以被撤消,而又不失去数据的一致性。为了隔离在共享数据上的并发的事务,数据库服务器应该跟踪被操作的数据,并在一个事务操作期间锁住数据。应用还应该维护数据库连接和事务之间的关联。为了实现可靠的锁定,应用构件应向数据库通知事务的终止。事务处理-体系看到了从头开始建造一个事务性应用的要点,考虑在一个在图堂中展示的事务处理体系下建造相同的应用。注意,尽管有多种可能的体系,它们将在后面的章节中讨论,图2中所展示的代表了本质的特征。BeainEnd图2:事务处理体系

这个体系介入了一个事务管理器和每个数据库(资源)一个的资源管理器。这些构件从应用构件(定单获得和定单处理)中抽象出了特定于事务的大多数要点,并分担事务实现的职责。下面讨论这个体系的各种构件。应用构件应用构件:职责•建立和界定事务•传播事务上下文•通过资源管理器操作数据应用构件是事务性资源的客户。它们是应用开发者用于实现商务事务的程序。在事务管理器的帮助下,这些构件建立全局事务,如果需要的话传播事务上下文,并在这些事务的范围内操作事务性资源。这些构件不负责实现保护事务的ACID属性。但是作为应用逻辑的一部分,这些构件通常做是提交还是回滚一个事务的决定。资源管理器资源管理器:职责•向事务服务器应征资源•参与两阶段提交和恢复协议一个资源管理器是一个管理持久和稳定的数据存储系统的构件,并且参与同事务管理器的两段提交和恢复协议。一个资源管理器典型的是一个稳定的存储系统上的一个驱动器或一个包装,有操作数据的接口(给应用构件),并且为了参与由事务服务器协调的两阶段提交和恢复协议。这个构件也可以,直接的或间接的,向事务管理器注册资源,这样事务管理器就可以追踪所有参与事务的资源。这个过程叫做资源征集。为了实现两阶段提交和恢复协议,资源管理器应该实现可能被恢复所使用的附加机制。资源管理器提供两套接口:一套给应用构件用来连接和完成对数据的操作,另套给事务管理器用来参与两阶段提交和恢复协议。事务管理器事务管理器:职责•建立和维护事务上下文•维护一个事务和特定的资源间的关联•发起并指挥两阶段提交和恢复协议•在开始两阶段提交和恢复过程之

前向应用构件们做同步呼叫事务管理器是一个事务处理环境的核心构件。它的主要职责是当应用构件要求时建立事务,允许资源征集和遣散,并指挥同资源管理器的两阶段提交或恢复协议。一个典型的事务性应用通过向事务管理器发出一个发起事务的请求来开始一个事务。作为响应,事务管理器开始一个事务并把它同一个呼叫线程联系在一起。事务管理器也建立一个事务上下文。在事务中的所有应用构件和/或线程共享事务上下文。初始发起开始事务的请求的线程,或者如果事务管理器允许的话,任何其他线程可以通过发起提交或回滚请求来最终终止事务。在一个事务被终止之前,在事务管理器所知道的多个数据上,多个构件和/或线程可以完成事务性操作。如果事务管理器允许的话,在事务最终完成之前,一个事务可以被挂起或被继续执行。一旦应用发起了提交请求,事务管理器为一个提交操作准备所有资源(通过指挥一次投票表决),并基于是否所有的资源都准备好了(就绪)提交,来发起对所有资源的一个提交或回滚请求。卜面的章节讨论事务处理相关的各种概念。事务处理-概念事务界定指定一个事务叫做事务界定(demarcation),通过把分布式的构件绑定到一个全局事务上来完成事务界定工作,它是标记构成一个事务的一组操作的一种方法。最常用的界定的途径是为事务处理标记执行操作的线程。这叫做编程界定。这样建立的事务可以通过去除标记而被挂起,并在以后通过从挂起点向恢复点显式的传播事务上下文来恢复执行。事务界定在向事务管理器的一个提交或一个回滚请求之后结束。提交请求指导所有参与的资源管理器永久的记录事务中的操作的效果。回滚请求使资源管理器撤消事务中所有操作的效果。一个可替代编程界定的是声明界定。基于构件的事务处理系统如Microsoft事务服务器、和基于应用服务器的事务处理系统如企业JavaBeans规范支持声明界定。在这种技术中,构件在部署时被标记为事务性的。这暗示了两件事。首先,界定的职责从应用转移到了容纳构件的容器(container)。为此,这种技术也叫做管理容器界定。其次,界定从应用建造期间(静态)延期到构件部署期间(动态)。事务上下文和传播因为多个应用构件和资源参与了一个事务,对于事务管理器建立和维护发生的事务的状态是必须的。这通常以事务上下文的形式完成。事务上下文是在资源上的事务性操作和调用操作的构件之间的一个关联(association)o在一个事务执行期间,所有的参与事务的线程共享事务上下文。所以事务上下文在逻辑上封装(envelop)了在一个事务期间在事务性资源上的完成的所有操作。事务上下文通常由底层的事务管理器透明的维护。资源征集资源征集是资源管理器向事务管理器报告它们参与一个事务的过程。这个过程使事务管理器可以跟踪参与一个事务的所有资源。资源管理器使用这些信息协调资源管理器完成的事务性工作,以及驱动两阶段提交和恢复协议。在事务结束时(一个提交或回滚之后)事务管理器遣散资源。在此之后,不再保持事务与资源之间的关联。两阶段提交这个事务管理器与所有应征一个事务的资源之间的协议确定是所有的资源管理器都提交事务还是它们都终止(abort)。在这个协议中,当应用要求提交事务时,事务管理器向所有涉及的资源管理器发起一个准备请求。每个这些资源可以依次发送一个回应来指示出它是否准备好(就绪)提交。只有当所有的资源管理器都准备好提交,事务管理器才向所有的资源管理器发起一个提交请求。否则,事务管理器发起一个回滚请求接着事务被滚回来。事务处理-标准和技术X/Open分布式事务处理模型X/Open分布式事务处理(DTP)模型是OpenGroup提出的一个分布式处理模型,OpenGroup是一个厂商财团。这个模型是在事务处理和数据库领域中多数商业厂商间的一个标准。这个模型由四个构件组成:应用程序:实现事务性操作。资源管理器:同于上面的讨论。事务管理器:同于上面的讨论。

通信资源管理器:方便在不同的事务处理领域中的不同的事务管理器之间的互操作。这个模型还定义了下列接口:1.TX接口:这是应用程序和事务管理器之间的接口,并由事务管理器实现。这个接口提供事务界定服务,允许应用程序把事务性操作绑定到一个全局事务中。这个接口由下列函数组成:表1:X/Open模型的TX接口函数功能tx_open打开一个事务管理器和相关联的组资源管理器。tx_close关闭一个事务管理器和相关联的一组资源管理器。tx_begin开始个新事务。tx_rollback回滚事务。tx_commit提父事务。tx_set_commit_return提交事务。(译注:原文如是)tx_set_transaction_control在链状和非链状模式间选择。在链状事务的情况下,工作被分成片段(piece),每个片段在一个平坦的(flat)事务控制之下。一旦完成了工作的一个片段,这个片段的提交或回滚不依赖于其他的片段的状态。tx_set_transaction_timeout设置一个事务超时间隔。tx_info返回事务信息,如它的标识符、事务的状态等。2.XA接口:这是一个资源管理器和事务管理器之间的双向接口。这个接口规定了两套函数。第一套叫xa_*()函数,由资源管理器实现,被事务管理器使用。表2:X/OpenDTP模型中的事务管理器的XA接口函数功能xa_start指导一个资源管理器把应用程序的后续的请求与个被提供的标识符所标识的事务关联起来。xa_end结束一个资源管理器与一个事务的关联。xa_prepare资源管理器为提交操作做准备。由事务管理器发起,是两阶段提交操作的第一阶段。xa_commit提交事务性操作。由事务管理器发起,是两阶段提交操作的第二阶段。xa_recover检索一个就绪的(prepared)列表,启发式的(heuristically)提交或启发式的回滚事务。xa_forget忘记同给定事务标识苻相关联的启发式(heuristic)事务。4.第二套函数叫ax_*()函数,由事务管理器实现,被资源管理器使用。表3:X/OpenDTP模型中的资源管理器的AX接口函数功能ax_reg动态的向一个事务管理器应征。ax_unreg动态的从一个事务管理器撤出。5.XA+接口:这个接口被用于支持通过通信资源管理器来跨越不同的事务管理器的全局事务。TXRPC接口:这个接口提供在一个全局事务中的不同的应用程序之间通信的可移植性。CRM-OSITP:是一个通信资源管理器和OSI事务处理服务之间的接口。X/OpenDTP模型在产业界中被确立的。一些商业事务管理产品,象TXSeries/Encina(完全附属于IBM的Tranarc的产品),Tuxedo和TopEnd(BEASystems的产品),还有AT&TGIS支持TX接口。尽管Microsoft的TransactionServer不支持TX接口,它还是能够同象Oracle这样的遵从XA的数据库互操作。类似的,多数商业数据库象Oracle,Sybase,Informix和MicrosoftSQLServer,以及消息中间件产品如IBM的MQSeries,和Microsoft的MSMQServer提供了XA接口的一个实现。OMG对象事务服务对象事务服务(OTS)是由对象管理组织(OMG)规定的分布式事务处理服务。这个规范扩展了CORBA模型并定义了一系列跨越(across)多个CORBA对象完成事务处理的接口。OTS模型基于X/OpenDTP模型之上并提供下列增强:•OTS模型把函数形式的XA和TX接口替换成了CORBA业接口。•在这个模型中的各种对象通过在IIOP之上的CORBA方法调用来通信。OTS可以同X/OpenDTP模型互操作。一个使用了事务性对象的应用可以使用事务管理器的TX接口来进行事务界定。OTS体系由下列构件组成:•事务客户:一个调用事务性对象上的操作的程序或对象。•事务性对象:一个封装(encapsulate)或参照(refersto)持久数据的CORBA对象,并且它的行为依赖于在一个事务期间是否调用它的操作。•可恢复对象:一个直接维护持久数据并且参与事务协议的事务性对象。•事务性服务器:一个或多个事务性对象的集合(collection)。•可恢复服务器:一个对象的集合,其中至少有一个是可恢复的。•资源对象:一个资源对象是为了参与两阶段提交和恢复协议而被注册的、在事务服务中的一个对象。除了通常的事务性语义,CORBAOTS还提供了下面的:•嵌套事务:这就允许一个应用建立一个嵌入在一个现存的事务中的事务。在这个模型中,多个子事务(subtransaction)可以递归的嵌入一个事务中。子事务可以提交或回滚而不提交或回滚它的父事务。但是,一个提交操作的结果要视事务的所有祖先的提交(commitment)状况而定。这个模型的主要优点是可以在一个精细的粒度上控制事务性操作。应用有一个在子事务层次上对错误进行改正或补偿的机会,而不用真正的去尝试提交整个父事务。•应用同步:使用OTS同步协议,在两阶段提交过程开始之前和完成之后,特定的对象可以为了通告而被注册在事务服务上。这使得应用对象可以同步暂时的(transient)状态和存储在持久存储中的数据。

图6:ORBacus®OTS体系(译者添加)卜面是CORBAOTS规范的原理上的接口:表4:CORBAOTS接口接口职责Current事务界定(begin,commit,rollback,rollback_only,set_time_out)事务的状态(get_status)•事务的名字(get_transaction_name)事务上下文(get_control)TransactionFactory显式的事务建立Control显式的事务上下文管理Terminator提交或回滚一个事务Coordinator事务的状态(get_status,get_parent_status,get_top_level_status)事务的信息(is_same_transaction,is_related_transaction,is_ancestor_transaction,is_descendant_transaction,

is_top_level_transaction,hash_transaciton,hash_top_level_transaction,get_transaction_name,get_txcontext)资源征集(register_resource,register_subtrans_aware)•同步对象的注册(register_synchronization)•为回滚而设置对象(rollback_only)建立子事务(create_subtransaction)RecoveryCoordinator在失败的情况下协调恢复(replay_completion)Resource参与两阶段提交和恢复协议(prepare,rollback,commit,commit_one_phase,forget)Synchronization在两阶段提交开始之前和完成之后的应用同步(before_completion,after_completion)SubtransactionAwareResource提交或回滚一个子事务,被事务服务调用(commit_subtransaction,rollback_subtransaction)TransactionalObject所有事务性对象都实现的个指小器(marker)接口下述产品提供OTS的实现:IntegratedTransactionService(Inprise的产品),OrbixOTM(Iona的产品),OTSARjuna(ArjunaSolutionsLimited的产品),和TPBroker(HitachiSoftware的产品).JTS和JTAJava事务服务和Java事务API是分布式计算领域中最新的竞争参加者。作为企业Java的发起者,SunMicrosystemsInc.在1999年提出了规范。(译注:1999年12月8日推出正式规范)OMGObjectTransactionService1.1JavaTransactionAPIJavaTransact!onServiceJavaTransactionalApplicdtions厂、¥JwaTransadionaiResourcesqqb5图3:Java事务的发起JTS规定一个Java事务管理器的实现。这个事务管理器支持JTA,应用服务器可以使用它建造支持事务性Java的应用。JTS的内部实现OMGOTS1.1规范的Java映射。Java映射被规定在两个包中:org.omg.CosTransactions和org.omg.CosTSPortability。尽管JTS是OMGObjectTransactionService1.1JavaTransactionAPIJavaTransact!onServiceJavaTransactionalApplicdtions厂、¥JwaTransadionaiResourcesqqb5图3:Java事务的发起JTA规定一个建造事务性应用服务器的体系,并为这个体系中各种构件定一系列的接口。这些构件是:应用构件,资源管理器,应用服务器,它们在图3中展示。JTS为事务性应用服务器和应用提供了一个新的体系,而在内部遵从OMGOTS1.1接口。这就允许遵从JTA的应用程序同其他的遵从OTS1.1的应用程序通过标准的IIOP来互操作。象在图3中展示的那样,在Java事务模型中,Java应用构件能通过JTS在遵从JTA的资源上指挥事务性操作。JTS扮演的是OTS之上的一个薄层。应用可以发起全局事务来包含其他OTS事务管理器,或参与到一个其他遵从OTS的事务管理器发起的全局事务。关于JTS和JTA的更详细的叙述请参见Java事务服务Microsoft事务服务器

Microsoft事务服务器(MTS)是一个基于构件的事务服务器,它的构件基于Microsoft的构件对象模型(COM)oMTS编程模型为建造事务性COM构件提供接口,而MTS运行环境提供一个部署和管理这些构件和管理事务的方法。使用了MTS,由多个COM构件做的工作可被组合在一个单一的事务中。不象本章讨论的其他技术,MTS是一个产品并且不基于开放的规范。还要注意,尽管MTS环境提供了一些其他特征,如资源缓冲池(pooling),对象重复利用(recycling),访问控制等,本节只聚焦于MTS的事务性的功能,并尝试把各种事务管理的概念映射到MTS环境。MTS体系高层的MTS体系在图4中展示:ResourceManagerApplication

ComponentApplicationComponentResourceManagerIApplicationResourceManagerApplication

ComponentApplicationComponentResourceManagerIApplicationComnonentnn-DistributedTransactionCoordinartorResourceDispenser■图4:Microsoft事务服务器MTS运行时环境(run-time):它是MTS构件的实例执行和被管理的环境。MTS运行时环境提供了MTS构件的部署和管理。它有以下特征:o分布式事务的管理o过程和线程的原子性管理o对象的(建立,缓冲(pooling)和重用)管理o控制对象的建立和使用的分布式安全服务MTSExplorer:这是一个图形用户界面驱动的工具,用来在MTS运行环境上部署和管理MTS构件。MTSExplorer也被用于通过分布式事务协调器来监控事务。分布式事务协调器(DTC):DTC是MTS的事务管理器。MTSAPI:MTSAPI(在MicrosoftVisualBasic,MicrosoftVisualC++和MicrosoftVisualJ++中)为建造事务性构件提供特定的接口和特定的具体的类。资源分发器(dispenser):一个MTS资源分发器代表MTS应用来管理非持久的共享的数据。MTS提供两个资源分发器:oODBC资源分发器:ODBC资源分发器本质上是一个ODBC驱动器的管理器,并有下列附加功能:・管理到遵从ODBC的数据库的连接的缓冲池,包括连接的回收和重用。・征集和遣散在MTS上下文对象上的数据库连接。o共享的属性管理器:MTS共享的属性管理器管理应用范围的特定于进程的属性(一对名字-值)并提供同步的访问这个数据。资源管理器:对于一个参与MTS事务的资源管理器,它必须支持下列协议之一:oOLE事务:这是一个基于COM的两阶段提交协议,资源管理器使用它来参与由DTC协调的事务。oX/OpenDTPXA协议:对于这个协议,MTS要求一个OLE事务到XA的映射器(mapper)。这个映射器在MTSSDK中提供。MTS对象和事务上下文一个MTS对象是一个MTS构件的一个实例(一个构件在MTS上被部署,并被MTS管理)。对于每个MTS对象,MTS建立和维护一个上下文对象(ObjectContext),它为一个MTS对象提供执行上下文。上下文对象也维护事务上下文的信息。资源分发器和DTC可以为事务界定,资源征集,遣散,两阶段提交等,访问这个事务上下文信息。注意,在MTS中,为每个MTS对象都维护事务上下文信息,而不是为所有参与一个事务的对象维护一个单一的事务上下文对象。事务结果每个MTS对象可以通过调用ObjectContext对象的一个方法,来参与决定一个事务的结果(outcome):SetComplete:通知MTS,对象已经成功的完成了它的工作,它的工作可以被提交了。SetAbort:通知MTS,对象的工作不能被提交。EnableCommit:对象的工作不是必须做完,但它的事务性工作可以用当前的形式被提交。DisableCommit:通知MTS,对象的工作不能用当前的形式被提交。事务界定MTS同时允许事务的编程界定和声明界定。对于在MTS上部署构件,声明界定是强制的。除此之外,MTS客户也可以通过编程发起和结束事务。•声明界定:依靠一个MTS构件的事务属性(property),MTS代表应用自动的开始一个事务。可能以有下列的事务属性(可以在部署期间设置):要求事务:构件的实例总是在一个事务的上下文中执行。希望调用(调用)对象在一个事务的上下文中被执行。要求新事务:构件的实例必须在它们自己的事务中执行,而不考虑调用对象是否已经开始了一个事务。支持事务:构件的实例可以在调用对象的事务(如果有的话)范围内执行。这暗示构件是事务安全的。不支持事务:构件的实例不在任何事务的范围内执行°MTS不把这样的构件做的工作同任何事务关联在一起。•编程界定:MTS客户可以使用TransactionContext对象用程序界定事务。一个客户可以通过建立TransactionContext对象的一个实例来开始一个事务,并通过调用这个对象的Commit或Abort方法来结束事务。所有在这些使用TransactionContext对象的边界内建立的MTS对象将在同一个事务上下文下执行。(除非构件设置为要求一个新事务或不支持事务)。MTS隐含的维护TransactionContext对象和事务的关联。资源征集MTS进行自动的资源征集。当一个MTS对象向资源分发器要求到一个资源的连接时,资源分发器获取调用对象的事务上下文,并用来它注册连接。经管MTS只能在MicrosoftWindows平台上获得,MTS可以同遵循XA协议的资源管理器互操作,并且在非Windows平台上操作的这样的资源管理器可以参与由DTC协调的事务。关于MTS的更多的信息请参阅MSDNlibrary。要得到MTS和其他竞争技术的一个快速而详细的特征汇编请参阅MTSFAQ.企业JavaBeans企业JavaBeans(EJB)是来自SunMicrosystemsInc的一个技术规范。它规定了一个建造基于构件的分布式应用的框架。在过去六个月中,符合这项技术的应用服务器已经从不同的厂商出现,而规范当前由SunMicrosystemsInc来不断改善。(译注:1998年3月24日推出正式的规范1.0).作为一个应用服务器框架,EJB服务器致力于事务处理,资源缓冲池,安全,线程,持久性,远程访问,生命周期等。但是同于MTS的情况,本节只聚焦于EJB框架的分布式事务性模型。EJB框架规定叫做enterprisebeans的构件的构造,部署和激发。EJB规范把enterprisebeans分成两类:实体(entity)beans和任务(session)beans。实体beans抽象的是持久域数据,任务beans提供特定的应用逻辑的任务。两种类型的beans被遵循EJB的服务器在叫做容器的东西中维护。一个容器为enterprisebeans提供运行时环境。图5展示了一个遵循EJB的应用服务器的简化了的体系。图中只展示了体系的各组成部分间的本质性的交互。EJBApplicationServer图5:在EJB应用服务器中的事务一个enterprisebean由两个接口来指定:home接口和remote接口。home接口指定如何建立和查找一个bean。通过这个接口,一个客户或其他bean可以获得驻留在一个EJB服务器上某个容器中的某个bean的一个引用。remote指定特定于应用的与实体或任务bean相关的方法。客户可以通过Java命名和目录接口(JavaNamingandDirectoryInterface:JNDI)机制获得enterprisebean的home接口的引用。一个EJB服务器应当为任何命名和目录服务器提供一个JNDI实现。通过使用这

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论