浅谈事务、COM 及分布式事务.doc_第1页
浅谈事务、COM 及分布式事务.doc_第2页
浅谈事务、COM 及分布式事务.doc_第3页
浅谈事务、COM 及分布式事务.doc_第4页
浅谈事务、COM 及分布式事务.doc_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

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

文档简介

浅谈事务、COM+及分布式事务 目录1 什么是事务及特性. 21.1 什么是事务:. 21.2 事务的特性(ACID原则):. 21.2.1 原子性(ATOMICITY): 21.2.2 一致性(CONSISTENCY):. 31.2.3 隔离性(ISOLATION):. 31.2.4 持久性(DURABILITY):. 32 事务应用的范围. 33 数据库中事务处理. 33.1 事务工作原理. 43.2 空间管理. 53.2.1 行级锁. 63.2.2 页级锁. 63.2.3 簇级锁. 73.2.4 表级锁. 83.2.5 数据库级锁. 83.3 死锁问题. 93.4 事务模式. 103.4.1 自动提交事务模式. 编译时错误的处理. 运行时错误的处理. 103.4.2 隐式提交事务模式. 113.4.3 显示提交事务模式. 123.5 事务中不支持的SQL语句. 124 什么叫分布式事务. 135 COM+简单介绍. 135.1 组件(Component)和对象(Object)之间的区别. 135.2 ActiveX、OLE和COM的关系. 135.3 COM、MTS与COM+. 155.3.1 DCOM. 155.3.2 MTS. 155.3.3 COM+的出现. 156 COM+与分布式事务. 166.1 Transaction Support所支持的属性:. 176.2 活动与同步. 176.3 事务的生存期. 186.3.1 事务开始. 196.3.2 建立与resource manager的连接. 196.3.3 执行操作. 206.3.4 表决事务的结果. 216.4 事务生存期小结. 227 在.NET中开发COM+实现分布事务. 227.1 开发事务型COM+组件. 227.2 COM+类示例. 237.3 利用TransactionScope类实现分布式事务. 257.4 在SQLServer2000中实现分布式事务. 257.4.1 访问格式:. 267.4.2 示例:. 268 .NET开发COM+注意事项. 269 配置与部署COM+. 279.1 配置MSDTC. 279.2 打开双方135端口. 289.3 注册COM+服务. 2810 开发中碰到的错误及处理办法. 281 什么是事务及特性1.1 什么是事务:简单的说,事务就是用户定义的一个操作序列(简单的说就是一条或多条数据执行语句,或者是其它的操作)的组合,如果其中的任一操作执行失败,则所有的操作都应撤销,还原到没有操作之前的状态,也就是说,操作序列中的操作要么都成功,要么都失败,是一个整体。1.2 事务的特性(ACID原则):事务必须要满足原子性、一致性、隔离性和持久性等四个特点,才能算是一个事务1.2.1 原子性(ATOMICITY):原子性用于标识事务是否完全地完成,一个事务的任何更新要在系统上完全完成,在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到操作前的状态。也就是说,一个事务要被完全的无二义性的做完或撤消。1.2.2 一致性(CONSISTENCY):一致性保证任何事务最后都处于有效状态,一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致状态转换到另一个一致状态。1.2.3 隔离性(ISOLATION):隔离性确保每一事务在系统中认为只有该事务在使用系统资源,在同一个环境中可能有多个事务并发执行和用到相同资源,这种属性有时称为串行化,也就是说,事务会独占相关资源,直到整个事务完成,在资源被占用期间,其它事务不能使用相关资源,直到被当前事务完成(数据库管理系统通常使用锁来实现)。在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。1.2.4 持久性(DURABILITY):持久性确保事务的变化是永久性的,持久性意味着一旦事务执行成功,在系统中产生的所有变化将是永久的。2 事务应用的范围只要在一次功能执行中,涉及到对多个资源进行操作(如对数据的增加、修改、删除)的情况,都需要应用事务。事务不仅是只存在于数据库中,在其它应用中,它无处不在,如 银行、证券交易系统;3 数据库中事务处理为了实现事务,数据库中引入了锁的机制。数据库中有多种锁,允许事务锁定不同的资源。锁就是保护指定的资源,在同一时间不被其他事务操作。为了最小化锁的成本,SQL Server自动地以与任务相应等级的锁来锁定资源对象。锁定比较小的对象,例如锁定行,虽然可以提高并发性,但是却有较高的开支,因为如果锁定许多行,那么需要占有更多的锁;锁定比较大的对象,例如锁定表,会大大降低并发性,因为锁定整个表就限制了其他事务访问该表的其他部分,但是成本开支比较低,因为只需维护比较少的锁。锁具有如下特点:l 锁是保证并发控制的手段 l 可以锁定的资源包括行、页、簇、表和数据库 l 锁类型主要包括共享锁和排它锁,特殊类型的锁包括意图锁、修改锁和模式锁 l 共享锁允许其他事务继续使用锁定的资源,排它锁只允许一个事务访问数据 l 系统本身可以处理死锁l 用户可以根据实际情况定制锁的一些特征使用事务时,原则上应该使事务尽可能的短并且要避免事务嵌套。3.1 事务工作原理事务确保数据的一致性和可恢复性。事务的工作原理如图1所示,事务开始之后,事务所有的操作都陆续写到事务日志中。写到日志中的操作,一般有两种:一种是针对数据的操作,一种是针对任务的操作。针对数据的操作,例如插入、删除和修改,这是典型的事务操作,这些操作的对象是大量的数据;针对任务的操作,例如创建索引,增加字段,这些任务操作在事务日志中记录一个标志,用于表示执行了这种操作,当取消这种事务时,系统自动执行这种操作的反操作,保证系统的一致性。系统自动生成一个检查点机制,这个检查点周期地发生。检查点的周期是系统根据用户定义的时间间隔和系统活动的频度由系统自动计算出来的时间间隔。检查点周期地检查事务日志,如果在事务日志中,事务全部完成,那么检查点将事务日志中的事务提交到数据库中,并且在事务日志中做一个检查点提交标记。如果在事务日志中,事务没有完成,那么检查点将事务日志中的事务不提交到数据库中,并且在事务日志中做一个检查点未提交标记。继续执行 事务开始 事务的每步操作写到日志中 检查点机制检查事务是否完成 事务写到日志中 成功 事务工作原理图(图1) 事务的恢复以及检查点保护系统的完整和可恢复,可以使用如图2所示的示例说明。 事务恢复和检查点示例图(图2)在这个示例图中,有五个事务:事务1、事务2、事务3、事务4和事务5。方框表示事务的开始和完成提交。水平方向表示时间。检查点表示在某一时间点发生检查点机制,系统失败表示在某一时间点由于断电、系统软件失败等原因而发生的系统失败。事务1的完成发生在检查点发生之间,所以事务1被提交到数据库中。事务2和事务4的完成发生在系统失败之前,所以这两个事务可以被系统向前滚动提交到数据库中。事务3和事务5由于系统失败而没有完成,所以这两个事务被取消。3.2 空间管理锁是防止其他事务访问指定的资源控制、实现并发控制的一种主要手段。为了提高系统的性能,加快事务的处理速度,缩短事务的等待时间,应该使锁定的资源最小化。为了控制锁定的资源,应该首先了解系统的空间管理。页:在SQL Server系统中,最小的空间管理单位是页,一个页有8K。所有的数据、日志、索引都存放在页上。另外,使用页有一个限制,这就是表中的一行数据必须在同一个页上,不能跨页(因此,我们在定义表结构时,所有字段所占空间之和不能超过8K的原因)。簇:页上面的空间管理单位是簇,一个簇是8个连续的页。表和索引:表和索引的最小占用单位是簇。数据库:数据库是由一个或者多个表或者索引组成,即是由多个簇组成。SQL Server系统的空间管理结构示意图如图3所示。 数据库 表 页 行 SQL Server空间管理(图3)3.2.1 行级锁行是可以锁定的最小空间。在SQL Server 7.0中,实现了行级锁。行级锁就是指事务在操纵数据的过程中,锁定一行或者若干行数据,其他事务不能同时处理这些行的数据。行级锁占用的数据资源最少,所以在事务的处理过程中,允许其他事务继续操纵同一个表或者同一个页的其他数据,大大降低了其他事务等待处理的时间,提高了系统的并发性。行级锁是一种最优锁,因为行级锁不可能出现数据既被占用又没有使用的浪费现象。在图4中,椭圆形表示行级锁占用的数据,而椭圆形之外的其他数据仍然可以由其他事务使用。行级锁是SQL Server 7.0的重要特征,它的引入引起了数据存储引擎的改变。行级锁(图4)3.2.2 页级锁页级锁是指在事务的操纵过程中,无论事务处理数据的多少,每一次都锁定一页,在这个页上的数据不能被其他事务操纵。在SQL Server 7.0以前,使用的是页级锁。页级锁锁定的资源比行级锁锁定的数据资源多。在页级锁中,即使是一个事务只操纵页上的一行数据,那么该页上的其他数据行也不能被其他事务使用。因此,当使用页级锁时,会出现数据的浪费现象,也就是说,在同一个页上会出现数据被占用却没有使用的现象。在这种现象中,数据的浪费最多不超过一个页上的数据行。在图5中,圆形区表示一个页级锁,在这个圆形区内,只有一个事务可以可以使用圆形区中的数据,其他事务只能使用圆形区以外的数据。页级锁(图5)3.2.3 簇级锁簇级锁是一种特殊类型的锁,只能用在一些特殊的情况下。簇级锁就是指事务占用一个簇,这个簇不能同时被其他事务占用。例如在创建数据库和创建表时,系统分配物理空间时使用这种类型的锁。系统是按照簇分配空间的。当系统分配空间时,使用簇级锁,防止其他事务同时使用同一个簇。当系统完成分配空间之后,就不再使用这种类型的簇级锁。特别是,当涉及到对数据操作的事务时,不使用簇级锁。簇级锁的结构如图6所示。椭圆形区域表示簇级锁占用的数据,其他事务只能使用该簇以外的其他簇。簇级锁(图6)3.2.4 表级锁表级锁也是一个非常重要的锁。表级锁是指事务在操纵某一个表的数据时,锁定了这个数据所在的整个表,其他事务不能访问该表中的其他数据。当事务处理的数据量比较大时,一般使用表级锁。表级锁的特点是使用比较少的系统资源,但是却占用比较多的数据资源。与行级锁和页级锁相比,表级锁占用的系统资源例如内存比较少,但是占用的数据资源却是最大。在表级锁时,有可能出现数据的大量浪费现象,因为表级锁锁定整个表,那么其他的事务都不能操纵表中的其他数据。这样,会延长其他事务等待处理的时间,降低系统的并发性能。表级锁的结构示意图如图8所示,椭圆形表示表级锁。表级锁(图7)3.2.5 数据库级锁数据库级锁是指锁定整个数据库,防止任何用户或者事务对锁定的数据库进行访问。数据库级锁是一种非常特殊的锁,它只是用于数据库的恢复操作过程中。这种等级的锁是一种最高等级的锁,因为它控制整个数据库的操作。只要对数据库进行恢复操作,那么就需要设置数据库为单用户模式,这样系统就能防止其他用户对该数据库进行各种操作。数据库级锁的结构示意图如图8所示。严格地说,数据库级锁不是一种锁,而是一种类似锁的一种单用户模式机制。但是,这种单用户模式机制非常类似锁机制,因此也可以把这种单用户模式称为数据库级锁。数据库锁(图8)3.3 死锁问题死锁是一个很重要的话题。在事务和锁的使用过程中,死锁是一个不可避免的现象。在两种情况下,可以发生死锁。第一种情况是,当两个事务分别锁定了两个单独的对象,这时每一个事务都要求在另外一个事务锁定的对象上获得一个锁,因此每一个事务都必须等待另外一个事务释放占有的锁,这时,就发生了死锁。这种死锁是最典型的死锁形式。在同一时间内有两个事务A和B,事务A有两个操作:锁定表part和请求访问表supplier;事务B也有两个操作:锁定表supplier和请求访问表part。结果,事务A和事务B之间发生了死锁,其示意进程如图9所示。死锁示意图(图9)死锁的第二种情况是,当在一个数据库中时,有若干个长时间运行的事务执行并行的操作,当查询分析器处理一种非常复杂的查询例如连接查询时,那么由于不能控制处理的顺序,有可能发生死锁现象。当发生死锁现象时,系统可以自动检测到,然后通过自动取消其中一个事务来结束死锁。在发生死锁的两个事务中,根据事务处理时间的长短作为规则来确定他们的优先级。处理时间长的事务具有较高的优先级,处理时间较短的事务具有较低的优先级。在发生冲突时,保留优先级高的事务,取消优先级低的事务。3.4 事务模式在SQL Server中,有三种事务模式:自动提交模式、隐性提交模式和显式提交模式,自动提交模式是SQL Server 的默认事务管理模式3.4.1 自动提交事务模式这是 SQL Server 的默认模式。每个单独的 SQL 语句都在其完成后提交,不需指定任何语句控制事务。如果在自动提交模式中的最后调用 commit,则会出错。 编译时错误的处理如果在一个批处理的SQL语句中(以GO分隔的一批语句就叫批处理SQL语句),有一个SQL语句有语法错误,则整个批处理不会被执行,这是因为编译错误将阻止 SQL Server 建立执行计划,所以批处理中的任何语句都没有执行,而不是因为执行了批处理又回滚整个批处理的情况。在如下示例中,由于编译时错误,第三个批处理中的任何 INSERT 语句都没有执行。但看上去好像是前两个 INSERT 语句执行了又被回滚:USE pubsGOCREATE TABLE TestTable (Field1 INT, Field2 VARCHAR(10)GOINSERT INTO TestTable VALUES (1, aaa)INSERT INTO TestTable VALUES (2, bbb)INSERT INTO TestTable VALUSE (3, ccc) - 有语法错误GOSELECT * FROM TestTable - 返回空行GO 运行时错误的处理运行时错误指的是在执行过程中产生的错误,对插入数据时键重复、对象不存在等,在下面的示例中,第三个 INSERT 语句产生运行时重复键错误。由于前两个 INSERT 语句成功地执行并且提交,因此它们在运行时错误之后被保留下来:USE pubsGOCREATE TABLE TestTable (Field1 INT PRIMARY KEY, Field2 CHAR(10)GOINSERT INTO TestTable VALUES (1, aaa)INSERT INTO TestTable VALUES (2, bbb)INSERT INTO TestTable VALUES (1, ccc) - 运行时产生主键重复错误GOSELECT * FROM TestTable - 返回插入的前二行数据GO由于SQL Server 使用延迟的名称解析,其中对象名直到执行时才被解析,下面的示例在语法上通过,但在执行时在下面的示例中,前两个 INSERT 语句执行并提交,当第三个 INSERT 语句由于引用了一个并不存在的表而产生运行时错误之后,前两行将仍然保留在 TestTable表中:USE pubsGOCREATE TABLE TestTable (Field1 INT PRIMARY KEY, Field2 CHAR(10)GOINSERT INTO TestTable VALUES (1, aaa)INSERT INTO TestTable VALUES (2, bbb)INSERT INTO TestTabl VALUES (3, ccc) - 表名少了一个字母e,表不存在GOSELECT * FROM TestTable - 返回前二行数据GO3.4.2 隐式提交事务模式通过SET IMPLICIT_TRANSACTIONS ON 语句,将隐性事务模式设置为打开,从此语句的下一个语句开始处,自动启动一个新事务,直到调用了 COMMIT或ROLLBACK语句或SET IMPLICIT_TRANSACTIONS OFF时,该事务完成。如果是在语句块的中间调用了COMMIT语句,则COMMIT语句的下一个 SQL 语句又将启动一个新事务,如此规律执行。下面的示例中,第三个批处理语句开启隐性事务模式,第四个批处理语句块在最后处调用 COMMIT提交,随后在第五个批处理语句块中,回滚隐性事务,第六个批处理语句插入数据,但没有显示调用COMMIT。USE pubsGOCREATE TABLE TestTable (Field1 INT PRIMARY KEY, Field2 CHAR(10)GOSET IMPLICIT_TRANSACTIONS ON - 将隐性事务模式设置为打开GOINSERT INTO TestTable VALUES (1, aaa) - 在此句处自动启动一个新事务INSERT INTO TestTable VALUES (2, bbb) - 包含在上面语句启动的事务范围内COMMIT - 在此调用事务提交语句,完成并结束开启的隐性事务GOINSERT INTO TestTable VALUES (3, ccc) - 此句处又自动启动一个新事务ROLLBACK - 回滚隐性事务,上面的插入语句失效GOINSERT INTO TestTable VALUES (4, ddd) - 此句处再次自动启动一个新事务GO SELECT * FROM TestTable 当前返回1、2、4数据GO对于通过设置了隐性事务为ON 而自动打开的事务,用户必须在该事务结束时将其显式提交或回滚。否则当用户断开连接时,事务及其所包含的所有数据更改将回滚。对于上面的执行结果,如果重新连接数据库执行SELECT * FROM TestTable 语句,则返回的结果是1、2数据。说明上面的示例在断开后,自动回滚了最后自动开启的隐性事务。3.4.3 显示提交事务模式通过发出 BEGIN TRANSACTION 语句显式启动事务。从该语句开始处,下面的所有语句都在一个事务中,直到碰到了COMMIT或ROLLBACK语句。显式事务模式持续的时间只限于该事务的持续期,当事务结束时,连接将返回到启动显式事务前所处的事务模式,或者是隐性模式,或者是自动提交模式。USE pubsGOBEGIN TRAN - 显示开启事务CREATE TABLE TestTable (Field1 INT PRIMARY KEY, Field2 CHAR(10)GOINSERT INTO TestTable VALUES (1, aaa)INSERT INTO TestTable VALUES (2, bbb)INSERT INTO TestTable VALUES (3, ccc) GOSELECT * FROM TestTable 在事务内执行,将返回1、2、3数据GOROLLBACK TRAN 回滚显示事务,事务内所有的操作都被回滚,包括创建表GOSELECT * FROM TestTable 此句执行时错误,因为库中不存在表GO3.5 事务中不支持的SQL语句在事务中,不支持对数据库、日志、配置等操作的SQL语句。SQL语句 功能 ALTER DATABASE 修改数据库 BACKUP LOG 备份日志 CREATE DATABASE 创建数据库 DISK INIT 创建数据库或事务日志设备 DROP DATABASE 删除数据库 DUMP TRANSACTION 转储事务日志 LOAD DATABASE 装载数据库备份复本 LOAD TRANSACTION 装载事务日志备份复本 RECONFIGURE 更新使用 sp_configure 系统存储过程更改的配置选项的当前配置(sp_configure 结果集中的 config_value 列)值 RESTORE DATABASE 还原使用BACKUP命令所作的数据库备份 RESTORE LOG 还原使用BACKUP命令所作的日志备份 UPDATE STATISTICS 在指定的表或索引视图中,对一个或多个统计组(集合)有关键值分发的信息进行更新 SP_DBOPTION 设置数据库选项 事务保存点,嵌套事务4 什么叫分布式事务要了解分布式事务,要先了解什么是分布式数据库系统,分布式数据库系统:指在物理上分散而逻辑上集中的数据库系统。其特点是:l 物理分布性,数据不在单个站点上, 按全局需求将数据划分成一定的数据子集,分散存储在各个站点上;l 逻辑整体性,各个站点上的数据子集, 相互间有严密的约束规则加以限定, 逻辑上是一个整体;l 站点自治性,各个站点上的数据(即LDB)是有本地的DBMS管理, 具有自治处理能力。分布式事务,就是在一个完整操作中,5 COM+简单介绍5.1 组件(Component)和对象(Object)之间的区别在了解COM相关知识之间,先了解组件与对象之间的区别。组件是一个可重用的模块,它是由一组处理过程、数据封装和用户接口组成的业务对象(Rules Object)。组件看起来像对象,但不符合对象的学术定义。它们的主要区别是:l 组件可以在另一个称为容器(有时也称为承载者或宿主)的应用程序中使用,也可以作为独立过程使用;l 组件可以由一个类构成,也可以由多个类组成,或者是一个完整的应用程序;l 组件为模块重用,而对象为代码重用。5.2 ActiveX、OLE和COM的关系大家或多或少都应该听说过ActiveX、OLE和COM/DCOM这些概念,但是他们之间是什么样的关系,可能并不完全清楚。从时间的角度讲,OLE是最早出现的,然后是COM和ActiveX;从体系结构角度讲,OLE和ActiveX是建立在COM之上的,所以COM是基础;单从名称角度讲,OLE、ActiveX是两个商标名称,而COM则是一个纯技术名词,这也是大家更多的听说ActiveX和OLE的原因。既然OLE是最早出现的,那么就从OLE说起,自从Windows操作系统流行以来,“剪贴板”(Clipboard)首先解决了不同程序间的通信问题(由剪贴板作为数据交换中心,进行复制、粘贴的操作),但是剪贴板传递的都是“死”数据,应用程序开发者得自行编写、解析数据格式的代码,于是动态数据交换(Dynamic Data Exchange,DDE)的通信协定应运而生,它可以让应用程序之间自动获取彼此的最新数据,但是,解决彼此之间的“数据格式”转换仍然是程序员沉重的负担。对象的链接与嵌入(Object Linking and Embedded,OLE)的诞生把原来应用程序的数据交换提高到“对象交换”,这样程序间不但获得数据也同样获得彼此的应用程序对象,并且可以直接使用彼此的数据内容,其实OLE是Microsoft的复合文档技术,它的最初版本只是瞄准复合文档,但在后续版本OLE2中,导入了COM。由此可见,COM是应OLE的需求而诞生的,所以虽然COM是OLE的基础,但OLE的产生却在COM之前。COM的基本出发点是,让某个软件通过一个通用的机构为另一个软件提供服务。COM是应OLE的需求而诞生,但它的第一个使用者却是OLE2,所以COM与复合文档间并没有多大的关系,实际上,后来COM就作为与复合文档完全无关的技术,开始被广泛应用。这样一来,Microsoft就开始“染指”通用平台技术。但是COM并不是产品,它需要一个商标名称。而那时Microsoft的市场专家们已经选用了OLE作为商标名称,所以使用COM技术的都开始贴上了OLE的标签。虽然这些技术中的绝大多数与复合文档没有关系。Microsoft的这一做法让人产生这样一个误解OLE是仅指复合文档呢?还是不单单指复合文档?其实OLE是COM的商标名称,自然不仅仅指复合文档。但Microsoft自己恐怕无法解释清楚,这要花费相当的精力和时间。于是,随着Internet的发展,在1996年春,Microsoft改变了主意,选择ActiveX作为新的商标名称。ActiveX是指宽松定义的、基于COM的技术集合,而OLE仍然仅指复合文档。当然,ActiveX最核心的技术还是COM。ActiveX和OLE的最大不同在于,OLE针对的是桌面上应用软件和文件之间的集成,而ActiveX则以提供进一步的网络应用与用户交互为主。到这里,大家应该对ActiveX、OLE和COM三者的关系有了一个比较明确的认识,COM才是最根本的核心技术,所以下面的重点COM。让对象模型完全独立于编程语言,这是一个非常新奇的思想。这一点从C+和Java的对象概念上,我们就能有所了解。但所谓COM对象究竟是什么呢?为了便于理解,可以把COM看作是某种(软件)打包技术,即把它看作是软件的不同部分,按照一定的面向对象的形式,组合成可以交互的过程和以组支持库。COM对象可以用C+、Java和VB等任意一种语言编写,并可以用DLL或作为不同过程工作的执行文件的形式来实现。使用COM对象的浏览器,无需关心对象是用什么语言写的,也无须关心它是以DLL还是以另外的过程来执行的。从浏览器端看,无任何区别。这样一个通用的处理技巧非常有用。例如,由用户协调运行的两个应用,可以将它们的共同作业部分作为COM对象间的交互来实现(当然,现在的OLE复合文档也能做到)。为在浏览器中执行从Web服务器下载的代码,浏览器可把它看作是COM对象,也就是说,COM技术也是一种打包可下载代码的标准方法(ActiveX控件就是执行这种功能的)。甚

温馨提示

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

评论

0/150

提交评论