多用户系统设计 陈龙超

上传人:m**** 文档编号:185811729 上传时间:2023-02-06 格式:DOCX 页数:9 大小:23.22KB
收藏 版权申诉 举报 下载
多用户系统设计 陈龙超_第1页
第1页 / 共9页
多用户系统设计 陈龙超_第2页
第2页 / 共9页
多用户系统设计 陈龙超_第3页
第3页 / 共9页
资源描述:

《多用户系统设计 陈龙超》由会员分享,可在线阅读,更多相关《多用户系统设计 陈龙超(9页珍藏版)》请在装配图网上搜索。

1、关于“多用户系统设计”的思考指导老师:姜志明姓名:陈龙超学号:20077610902班级:07级一班 本文主要从以下几个方面谈谈自己对多“用户系统”的认识。第一:什么是多用户系统?多用户系统,顾名思义就是支持多个用户同时使用的系统。这是在网上搜“多用户” 出现最多的定义。而且对于很多学过软件开发的同学来说,关于多用户的理解也不出其右。 这种理解不能说是错误的,只能说是不恰当的,对多用户系统的理解应该在它支持多用户的 “支持”度上。简单的多用户系统和真正意义上的多用户系统是两种完全不同的概念。简单的多用户系统,并没有牵扯到数据的并发处理。就像我们在昆山实训的时候,我 们小组开发过一个“家庭财务管

2、理系统”,这个系统是一个简单的模拟网站系统。刚开始设 计的时候,我们就想把它做成支持多家庭的财务管理系统。做完才发现根本就没有需要并发 处理的数据,但发布之后依然能支持多个家庭同时在线进行操作。所以这种系统并不是真正 意义上的多用户系统。真正意义上的多用户系统,按照姜老师的说法就是:能解决并发问题的系统才是多用 户系统。应为多用户系统的优点,也就是多用户系统的目的就是:实现数据的共享。数据一 旦共享就意味着没个使用系统的用户都有操作这些数据的可能。这样的话,数据的一致性和 完整行就没法保证了。也就是说多用户的根本就实现数据的共享,而且要保证数据的一致性和完整行不被破 环。第二:用户系统并发控制

3、所以在了解了多用户的本质之后,当我们在设计多用户系统的时候我们就知道该怎么 做了。首先,我们知道只有同一个数据在被多个用户同时操作的时候才会出现并发情况。所 以在我们设计多用户系统的时候,要明确这个系统是不是有并发情况的出现。其次,除了按照正常的软件工程管理方法和结构化程序设计来对系统的开发和管理外, 要特别注意在数据库设计阶段对数据字段的设计考量。最后,还是要实现并发控制,让系统真正意义上支持多用户同时使用。从以上的讨论中我们可以看出来,解决多用户系统就是要弄明白并发控制的机制。而 要弄清楚并发控制的机制,我们又要弄明白2个概念:事务和锁。一事务事务(Transaction )是并发控制的基

4、本单位。所谓的事务,它是一个操作序列,这些操作要 么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转账工作:从一个账 号扣款并使另一个账号增款,这两个操作要么都执行,要么都不执行。所以,应该把它们看 成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致 性。针对上面的描述可以看出,事务的提出主要是为了解决并发情况下保持数据一致性 的问题。事务具有以下4个基本特征。 Atomic (原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要 么全部成功,要么全部失败。 Consistency (一致性):只有合法的数据可以被写入数据库,否则事务

5、应该将其回滚到 最初状态。 Isolation (隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的 正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。 Durability (持久性):事务结束后,事务处理的结果必须能够得到固化。数据库肯定是要被广大客户所共享访问的,那么在数据库操作过程中很可能出现以 下几种不确定情况。 更新丢失(Lost update):两个事务都同时更新一行数据,但是第二个事务却中途失败 退出,导致对数据的两个修改都失效了。这是因为系统没有执行任何的锁操作,因此并发事 务并没有被隔离开来。 脏读取(Dirty Reads): 一个事务

6、开始读取了某行数据,但是另外一个事务已经更新了 此数据但没有能够及时提交。这是相当危险的,因为很可能所有的操作都被回滚。 不可重复读取(Non-repeatable Reads): 一个事务对同一行数据重复读取两次,但是却 得到了不同的结果。例如,在两次读取的中途,有另外一个事务对该行数据进行了修改,并 提交。 两次更新问题(Second lost updates problem):无法重复读取的特例。有两个并发事务 同时读取同一行数据,然后其中一个对它进行修改提交,而另一个也进行了修改提交。这就 会造成第一次写操作失效。 虚读(Phantom Reads):事务在操作过程中进行两次查询,第二

7、次查询的结果包含了第 一次查询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询 过程中有另外一个事务插入数据造成的。数据库的隔离级别为了避免上面出现的几种情况,在标准SQL规范中,定义了 4个事务隔离级别,不同的隔离级别对事务的处理不同。 未授权读取(Read Uncommitted):允许脏读取,但不允许更新丢失。如果一个事务已 经开始写数据,则另外一个数据则不允许同时进行写操作,但允许其他事务读此行数据。该 隔离级别可以通过“排他写锁”实现。 授权读取(Read Committed):允许不可重复读取,但不允许脏读取。这可以通过,瞬间 共享读锁”和“排他写锁”实现

8、。读取数据的事务允许其他事务继续访问该行数据,但是未提 交的写事务将会禁止其他事务访问该行。 可重复读取(Repeatable Read):禁止不可重复读取和脏读取,但是有时可能出现幻影 数据。这可以通过“共享读锁”和“排他写锁”实现。读取数据的事务将会禁止写事务(但允许 读事务),写事务则禁止任何其他事务。 序列化(Serializable):提供严格的事务隔离。它要求事务序列化执行,事务只能一个 接着一个地执行,但不能并发执行。如果仅仅通过“行级锁”是无法实现事务序列化的,必须 通过其他机制保证新插入的数据不会被刚执行查询操作的事务访问到。隔离级别越高,越能保证数据的完整性和一致性,但是对

9、并发性能的影响也越大。 对于多数应用程序,可以优先考虑把数据库系统的隔离级别设为Read Committed,它能够 避免脏读取,而且具有较好的并发性能。尽管它会导致不可重复读、虚读和第二类丢失更新 这些并发问题,在可能出现这类问题的个别场合,可以由应用程序采用悲观锁或乐观锁来控 制。通过前面的介绍已经知道,通过选用不同的隔离等级就可以在不同程度上避免前面 所提及的在事务处理中所面临的各种问题。所以,数据库隔离级别的选取就显得尤为重要, 在选取数据库的隔离级别时,应该注意以下几个处理的原则:首先,必须排除“未授权读取”,因为在多个事务之间使用它将会是非常危险的。事 务的回滚操作或失败将会影响到

10、其他并发事务。第一个事务的回滚将会完全将其他事务的操 作清除,甚至使数据库处在一个不一致的状态。很可能一个已回滚为结束的事务对数据的修 改最后却修改提交了,因为“未授权读取”允许其他事务读取数据,最后整个错误状态在其他 事务之间传播开来。其次,绝大部分应用都无须使用“序列化”隔离(一般来说,读取幻影数据并不是一 个问题),此隔离级别也难以测量。目前使用序列化隔离的应用中,一般都使用悲观锁,这 样强行使所有事务都序列化执行。剩下的也就是在“授权读取”和“可重复读取”之间选择了。我们先考虑可重复读取。 如果所有的数据访问都是在统一的原子数据库事务中,此隔离级别将消除一个事务在另外一 个并发事务过程

11、中覆盖数据的可能性(第二个事务更新丢失问题)。这是一个非常重要的问 题,但是使用可重复读取并不是解决问题的唯一途径。假设使用了“版本数据”,Hibernate会自动使用版本数据。Hibernate的一级Session 缓存和版本数据已经为你提供了“可重复读取隔离”绝大部分的特性。特别是,版本数据可以 防止二次更新丢失的问题,一级Session缓存可以保证持久载入数据的状态与其他事务对数 据的修改隔离开来,因此如果使用对所有的数据库事务采用授权读取隔离和版本数据是行得 通的。“可重复读取”为数据库查询提供了更好的效率(仅对那些长时间的数据库事务),但 是由于幻影读取依然存在,因此没必要使用它(对

12、于Web应用来说,一般也很少在一个数 据库事务中对同一个表查询两次)。也可以同时考虑选择使用Hibernate的二级缓存,它可以如同底层的数据库事务一样 提供相同的事务隔离,但是它可能弱化隔离。假如在二级缓存大量使用缓存并发策略,它并 不提供重复读取语义(例如,后面章节中将要讨论的读写,特别是非严格读写),很容易可 以选择默认的隔离级别:因为无论如何都无法实现“可重复读取”,因此就更没有必要拖慢数 据库了。另一方面,可能对关键类不采用二级缓存,或者采用一个完全的事务缓存,提供“可 重复读取隔离”。那么在业务中需要使用到“可重复读取”吗?如果你喜欢,当然可以那样做, 但更多的时候并没有必要花费这

13、个代价。下面让我们看一下多事务执行方式:(1)事务串行执行每个时刻只有一个事务运行,其他事务必须等到这个事务结束一会方能运行不能充分利用系统资源,发挥数据库共享资源的特点(2)交叉并发方式事务的并行执行是这些并行事务的并行操作轮流交叉运行是单处理机系统中的并发方式,能够减少处理机的空闲时间,提高系统的效率(3)同时并发方式多处理机系统中,每个处理机可以运行一个事务,多个处理机可以同时运行多个事 务,实现多个事务真正的并行运行最理想的并发方式,但受制于硬件环境更复杂的并发方式所以,并发控制机制的任务就是:对并发操作进行正确的调度保证事务的隔离性保证数据库的一致性V二锁首先我们先了解一下锁的概念:

14、一. 为什么要引入锁AA多个用户同时对数据库的并发操作时会带来以下数据不一致 的问题:AA丢失更新AA,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏 了另一个修改的结果,比如订票系统AA脏读入A用户修改了数据,随后B用户又读出该数据, 但A用户因为某些原因取消了对数据的修改,数据恢复原值,此时B得到的数据就与数据库内 的数据产生了不一致AA不可重复读入A用户读取数据,随后B用户读出该数据并修改,此时 A用户再读取数据时发现前后两次的值不一致AA并发控制的主要方法是封锁,锁就是在一 段时间内禁止用户做某些操作以避免产生数据不一致AA二. 锁的分类AA锁的类别有两种分法:AA1.从数

15、据库系统的角度来看:分为独占 锁(即排它锁),共享锁和更新锁AAMS-SQL Server使用以下资源锁模式。AA锁模式 描 述A共享(S)用于不更改或不更新数据的操作(只读操作),如SELECT语句。A更新(U) 用于可更新的资源中。防止当多个会话在读取、锁定以及随后可能进行的资源更新时发生常 见形式的死锁。入排它(X)用于数据修改操作,例如INSERT、UPDATE或DELETE。 确保不会同时同一资源进行多重更新。A意向锁用于建立锁的层次结构。意向锁的类型为: 意向共享(IS)、意向排它(IX)以及与意向排它共享(SIX)。A架构锁在执行依赖于表架 构的操作时使用。架构锁的类型为:架构修

16、改(Sch-M)和架构稳定性(Sch-S)。A大容量 更新(BU)向表中大容量复制数据并指定了 TABLOCK提示时使用。AA共享锁A共享 (S)锁允许并发事务读取(SELECT) 一个资源。资源上存在共享(S)锁时,任何其它事务 都不能修改数据。一旦已经读取数据,便立即释放资源上的共享(S)锁,除非将事务隔离 级别设置为可重复读或更高级别,或者在事务生存周期内用锁定提示保留共享(S)锁。AA 更新锁A更新(U)锁可以防止通常形式的死锁。一般更新模式由一个事务组成,此事务读 取记录,获取资源(页或行)的共享(S)锁,然后修改行,此操作要求锁转换为排它(X)锁。 如果两个事务获得了资源上的共享模

17、式锁,然后试图同时更新数据,则一个事务尝试将锁转 换为排它(X)锁。共享模式到排它锁的转换必须等待一段时间,因为一个事务的排它锁与 其它事务的共享模式锁不兼容;发生锁等待。第二个事务试图获取排它(X)锁以进行更新。 由于两个事务都要转换为排它(X)锁,并且每个事务都等待另一个事务释放共享模式锁, 因此发生死锁。AA若要避免这种潜在的死锁问题,请使用更新(U)锁。一次只有一个事 务可以获得资源的更新(U)锁。如果事务修改资源,则更新(U)锁转换为排它(X)锁。否则,锁转换为共享锁。AA排它锁A排它(X)锁可以防止并发事务对资源进行访问。其 它事务不能读取或修改排它(X)锁锁定的数据。AA意向锁A

18、意向锁表示SQL Server需 要在层次结构中的某些底层资源上获取共享(S)锁或排它(X)锁。例如,放置在表级的共 享意向锁表示事务打算在表中的页或行上放置共享(S)锁。在表级设置意向锁可防止另一 个事务随后在包含那一页的表上获取排它(X)锁。意向锁可以提高性能,因为SQL Server 仅在表级检查意向锁来确定事务是否可以安全地获取该表上的锁。而无须检查表中的每行或 每页上的锁以确定事务是否可以锁定整个表。AA意向锁包括意向共享(IS)、意向排它(IX) 以及与意向排它共享(SIX)。AA锁模式描述A意向共享(IS)通过在各资源上放置S 锁,表明事务的意向是读取层次结构中的部分(而不是全部

19、)底层资源。A意向排它(IX)通 过在各资源上放置X锁,表明事务的意向是修改层次结构中的部分(而不是全部)底层资 源。IX是IS的超集。A与意向排它共享(SIX)通过在各资源上放置IX锁,表明事务 的意向是读取层次结构中的全部底层资源并修改部分(而不是全部)底层资源。允许顶层资 源上的并发IS锁。例如,表的SIX锁在表上放置一个SIX锁(允许并发IS锁),在当 前所修改页上放置IX锁(在已修改行上放置X锁)。虽然每个资源在一段时间内只能有 一个SIX锁,以防止其它事务对资源进行更新,但是其它事务可以通过获取表级的IS锁 来读取层次结构中的底层资源。AA独占锁:只允许进行锁定操作的程序使用,其他

20、任何 对他的操作均不会被接受。执行数据更新命令时,SQL Server会自动使用独占锁。当对象上 有其他锁存在时,无法对其加独占锁。入共享锁:共享锁锁定的资源可以被其他用户读取, 但其他用户无法修改它,在执行Select时,SQL Server会对对象加共享锁。A更新锁:当SQL Server准备更新数据时,它首先对数据对象作更新锁锁定,这样数据将不能被修改,但可以 读取。等到SQL Server确定要进行更新数据操作时,他会自动将更新锁换为独占锁,当对象 上有其他锁存在时,无法对其加更新锁。AA2.从程序员的角度看:分为乐观锁和悲观锁。 A乐观锁:完全依靠数据库来管理锁的工作。A悲观锁:程序

21、员自己管理数据或对象上的 锁处理。入入MS-SQLSERVER使用锁在多个同时在数据库内执行修改的用户间实现悲观并 发控制AA三. 锁的粒度A锁粒度是被封锁目标的大小,封锁粒度小则并发性高,但开销大,封锁粒 度大则并发性低但开销小AASQL Server支持的锁粒度可以分为为行、页、键、键范围、索 引、表或数据库获取锁AA资源 描述ARID行标识符。用于单独锁定表中的一行。入键 索 引中的行锁。用于保护可串行事务中的键范围。入页8千字节(KB)的数据页或索引页。 入扩展盘区相邻的八个数据页或索引页构成的一组。入表包括所有数据和索引在内的整 个表。ADB数据库。AA四锁定时间的长短AA锁保持的时

22、间长度为保护所请求级别上 的资源所需的时间长度。AA用于保护读取操作的共享锁的保持时间取决于事务隔离级别。 采用READ COMMITTED的默认事务隔离级别时,只在读取页的期间内控制共享锁。在扫 描中,直到在扫描内的下一页上获取锁时才释放锁。如果指定HOLDLOCK提示或者将事 务隔离级别设置为REPEATABLE READ或SERIALIZABLE,则直到事务结束才释放锁。 AA根据为游标设置的并发选项,游标可以获取共享模式的滚动锁以保护提取。当需要滚动 锁时,直到下一次提取或关闭游标(以先发生者为准)时才释放滚动锁。但是,如果指定 HOLDLOCK,则直到事务结束才释放滚动锁。AA用于保

23、护更新的排它锁将直到事务结束 才释放。入如果一个连接试图获取一个锁,而该锁与另一个连接所控制的锁冲突,则试图 获取锁的连接将一直阻塞到:AA将冲突锁释放而且连接获取了所请求的锁。AA连接的 超时间隔已到期。默认情况下没有超时间隔,但是一些应用程序设置超时间隔以防止无限期 等待AA五SQL Server中锁的自定义AA1处理死锁和设置死锁优先级AA死锁就是多 个用户申请不同封锁,由于申请者均拥有一部分封锁权而又等待其他用户拥有的部分封锁而 引起的无休止的等待AA可以使用SET DEADLOCK_PRIORITY控制在发生死锁情况时会 话的反应方式。如果两个进程都锁定数据,并且直到其它进程释放自己

24、的锁时,每个进程才 能释放自己的锁,即发生死锁情况。AA2处理超时和设置锁超时持续时间。 AALOCK_TIMEOUT返回当前会话的当前锁超时设置,单位为毫秒 AASET LOCK_TIMEOUT设置允许应用程序设置语句等待阻塞资源的最长时间。当语句等待的时 间大于LOCK_TIMEOUT设置时,系统将自动取消阻塞的语句,并给应用程序返回已超 过了锁请求超时时段的1222号错误信息AA示例A下例将锁超时期限设置为1,800毫 秒。 ASET LOCK_TIMEOUT 1800 AA3)设置事务隔离级别。 AA4 )对 SELECT、 INSERT、UPDATE和DELETE语句使用表级锁定提示

25、。AA5)配置索引的锁定粒度A 可以使用sp_indexoption系统存储过程来设置用于索引的锁定粒度 AA六查看锁的信息 AA1执行EXEC SP_LOCK报告有关锁的信息A2查询分析器中按Ctrl+2可以看到锁的 信息AA七使用注意事项AA如何避免死锁入1使用事务时,尽量缩短事务的逻辑处理过 程,及早提交或回滚事务;A2设置死锁超时参数为合理范围,如:3分钟-10分种;超过 时间,自动放弃本次操作,避免进程悬挂;A3优化程序,检查并避免死锁现象出现;A4 . 对所有的脚本和SP都要仔细测试,在正是版本之前。A5所有的SP都要有错误处理(通过 error)A6 一般不要修改SQL SERV

26、ER事务的默认级别。不推荐强行加锁AA解决问题 如何对行表数据库加锁AA八几个有关锁的问题AA1如何锁一个表的某一行AASET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED AASELECT * FROM table ROWLOCK WHERE id = 1 AA2 锁定数据库的一个表 AASELECT * FROM table WITH (HOLDLOCK) AA加锁语句: 入Sybase:入update 表 set coll=coll where 1=0 ; AMSSQL: 入select coll from 表(tablockx) where

27、1=0 ; Aoracle:入LOCK TABLE 表 IN EXCLUSIVE MODE ; A加锁后其它人不可操作,直到加锁用户解锁,用commit或rollback解锁AAA几 个例子帮助大家加深印象 A设table1(A,B,C) AA B C Aal bl cl Aa2 b2 c2 Aa3 b3 c3 AA1 )排 它锁A新建两个连接 A在第一个连接中执行以下语句 入begin tran Aupdate tablel Aset A=aa Awhere B=b2 Awaitfor delay 00:00:30-等待30秒 Acommit tran A在第二个连接中执 行以下语句 Abe

28、gin tran Aselect * from tablel Awhere B=b2 Acommit tran AA 若同时执行上 述两个语句,则select查询必须等待update执行完毕才能执行即要等待30秒AA2 )共享锁A 在第一个连接中执行以下语句 Abegin tran Aselect * from tablel holdlock -holdlock人为加锁 Awhere B=b2 Awaitfor delay 00:00:30-等待30秒 Acommit tran AA 在第二个连接中执行以 下语句 Abegin tran Aselect A,C from tablel Awhe

29、re B=b2 Aupdate tablel Aset A=aa Awhere B=b2 Acommit tran AA若同时执行上述两个语句,则第二个连接中的select查询可以执行A 而update必须等待第一个事务释放共享锁转为排它锁后才能执行即要等待30秒AA3)死锁 A增设table2(D,E) AD E Adl el Ad2 e2 A 在第一个连接中执行以下语句 Abegin tran Aupdate tablel Aset A=aa Awhere B=b2 Awaitfor delay 00:00:30 Aupdate table2 Aset D=d5 Awhere E=el A

30、commit tran AA在第二个连接中执行以下语句 Abegin tran Aupdate table2 Aset D=d5 Awhere E=el Awaitfor delay 00:00:l0 Aupdate tablel Aset A=aa Awhere B=b2 Acommit tran AA同时执行,系统会检测出死锁,并中止进程AA补充一点:ASql Server2000 支持的表级锁定提示AAHOLDLOCK持有共享锁,直到整个事务完成,应该在被锁对象 不需要时立即释放,等于SERIALIZABLE事务隔离级别AANOLOCK语句执行时不发出共 享锁,允许脏读,等于READ U

31、NCOMMITTED事务隔离级别AAPAGLOCK在使用一个 表锁的地方用多个页锁AAREADPAST让sql server跳过任何锁定行,执行事务,适用于 READ UNCOMMITTED事务隔离级别只跳过RID锁,不跳过页,区域和表锁 AAROWLOCK 强制使用行锁AATABLOCKX强制使用独占表级锁,这个锁在事务期间阻止任何其他事务 使用这个表AAUPLOCK强制在读表时使用更新而不用共享锁AA应用程序锁:A应用程 序锁就是客户端代码生成的锁,而不是sql server本身生成的锁AA处理应用程序锁的两个过 程AAsp_getapplock锁定应用程序资源AAsp_releaseap

32、plock为应用程序资源解锁AA注 意:锁定数据库的一个表的区别 入入SELECT * FROM table WITH (HOLDLOCK)其他事务 可以读取表,但不能更新删除AASELECT * FROM table WITH (TABLOCKX)其他事务不 能读取表,更新和删除。A由以上的描述可以看出,在实际系统的开发过程中,有时候将锁机制与事务的使用结合 起来才能更好保证系统在多用户共同使用的情况下保持良好的并发性。第三:总结在对并发控制的机制讨论中,我们发现数据共享与数据一致性是一对矛盾,数据库的 价值在很大程度上取决于它所能提供的数据共享度,而数据共享在很大程度上取决于系统允 许对数据并发操作的程度,数据并发程度又取决于并发控制机制;另一方面,数据的一致性 也取决于并发控制的程度。施加的并发控制愈多,数据的一致性往往愈好。所以在多用户系统的设计中,并发控制的“度”需要我们好好的去衡量。

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!