管理大批量并发处理

  1. 云栖社区>
  2. 博客>
  3. 正文

管理大批量并发处理

科技小能手 2017-11-15 20:19:00 浏览710
展开阅读全文
  何为并发: 同时访问一种资源的用户被视为并发访问资源。并发数据访问需要某些机制,以防止多个用户试图修改其他用户正在使用的资源时产生负面影响。
  管理并发: 并发影响  并发控制的类型  数据库引擎中的隔离级别
  并发影响: 丢失更新  未提交的依赖关系(脏读)  不一致的分析(不可重复读)  幻读
  丢失更新: 当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其他事务的存在。最后的更新将覆盖由其他事务所做的更新,这将导致数据丢失。
               例如,两个编辑人员制作了同一文档的电子副本。每个编辑人员制作了同一文档的电子副本。每个编辑人员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档。最后保存其更改副本的编辑人员覆盖另一个编辑人员所做的更改。如果在一个编辑人员完成并提交事务之前,另一个编辑人员不能访问同一文件,则可避免此问题。
  未提交的依赖关系(脏读): 当第二个事务选择其他事务正在更新的行时,会发生未提交的依赖关系问题。第二个事务正在读取的数据还没有提交并且可能由更新此行的事务所更改。
                                 例如,一个编辑人员正在更改电子文档。在更改过程中,另一个编辑人员复制了该文档(该副本包含到目前为止所做的全部更改)并将其分发给预期的用户。此后,第一个编辑人员认为目前所做的更改是错误的,于是删除了所做的编辑并保存了文档。分发给用户的文档包含不再存在的编辑内容,并且这些编辑内容应视为从未存在过。如果在第一个编辑人员保存最终更改并提交事务之前,任何人都不能读取更改的文档,则可以避免此问题。
  不一致的分析(不可重复读): 当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。不一致的分析与未提交的依赖关系类似,因为其他事务也是正在更改第二个事务正在读取的数据。但是,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。此外,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都被其他事务更改,因此我们称之为"不可重复读"。                        
                                   例如,编辑人员两次读取同一文档,但在两次读取之间,作者重写了该文档。当编辑人员第二次读取文档时,文档已更改。原始读取不可重复。如果在编辑人员完成最后一次读取文档之前,作者不能更改文档,则可以避免此问题。
  幻读: 当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻读问题。由于其他事务的删除操作,事务第一次读取的行的范围显示有一行不再存在于第二次或后续读取内容中。同样,由于其他事务的插入操作,事务第二次或后续读取的内容显示有一行并不存在于原始读取内容中。
         例如,一个编辑人员更改作者提交的文档,但当生产部门将其更改内容合并到该文档的主副本时,发现作者已将未编辑的新材料添加到该文档中。与不可重复读的情况相似,如果在编辑人员和生产部门完成对原始文档的处理之前,任何人都不能将新材料添加到文档中,则可以避免此问题。
  可用性和锁: ACID Transaction Design Requirements-->原子性(Atomicity)  一致性(Consistency) 隔离性(Isolation) 持久性(Durability)  隔离级别-->Level 0-读未提交(Read Uncommitted) Level 1-读提交(Read Committed) Level 2-可重复读(Repeatable Reads) Level 3-可串行(Serializable)  在2000/2005中默认隔离级别是ANSI/ISO Level 1,Read Committed 
  隔离级别0-读未提交(锁现象: 脏读)--> 一个读事务可以读另一个事务的未提交的改变A,导致了"脏读  DML语句总是使用排他锁  原理: 对于脏读事务没有使用行销(使用了SCH_S锁),所读出的数据可能是无效的。 产生现象: 因为数据被修改中,所读出的结果可能是无效的(Rolled back)
  隔离级别1-读提交(锁现象: 不一致分析/不可重复读)-->所有版本的默认行为  正在修改中的数据不能被另一个事务读,仅当提交后方可访问。一个事务中,select语句执行完毕后,在事务结束之前,其他事务便可修改这些数据。 DML语句总是使用排他锁  原理: 在一个事务中,读操作发出行锁,当行被检索后,锁就释放(修改不释放锁),而无需等到事务结束,这样别的事务就可以访问这些行。 产生现象: 在一个事务中,再次读的结果会不一样--不可重复读。但它消灭了脏读。
  隔离级别2-可重复读(现象: 幻影)-->正在进行中的事务的数据被上锁,即便select执行完,别的事务也不能修改这些数据,只能读取这些数据。从而在一个事务中两次读结果一样。并发低于默认隔离级别,只应在必要时才用。 原理: 在事务执行期间,读锁一直被保持,因此别的事务不能修改这些数据,重复读成为可能。 产生现象: 在事务开始时未检索出的行可能会在后续的检索中出现。这种现象被称之为幻影。
  隔离级别3-可串行(锁现象: 无)-->在数据集上放置一个范围锁,以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低,所以应只在必要时才使用该选项。该选项的作用与在事务内所有SELECT语句中的所有表上设置HOLDLOCK相同。 原理: 事务中的锁被保持在一个更高的级别上,利用索引产生key range锁,从而阻止对数据库集的插入。 副作用: 为了阻止向数据集插入行,数据集需要被锁定。如果没有合适的索引,那么便有可能产生更高级别的所,如表锁,而非范围锁。
  并发控制的类型: 悲观并发控制  乐观并发控制  Microsoft SQL Server 2005支持某个范围的并发控制。用户通过为游标上的连接或并发选项选择事务隔离级别来指定并发控制的类型。这些特性可以使用Transact-SQL语句或通过数据库应用程序编程接口(API,如ADO、ADO.NET、OLE DB和ODBC)的属性和特性来定义
  运行SET TRANSACTION ISOLATION LEVEL Transact-SQL语句。 使用System.Data.SqlClient的ADO.NET应用程序可以使用SqlConnection.Begin Transaction方法来指定IsolationLevel选项。 使用ADO的应用程序可以设置"自动提交隔离级别"属性。 使用OLE DB的应用程序可以调用ITransactionLocal: Start Transaction,其中isoLevel设置为所需的事务隔离级别。 使用ODBC的应用程序可以使用SQLSetConnectAttr来设置SQL_COPT_SS_TXN_ISOLATION属性。
  数据库引擎中的隔离级别: SQL-99标准定义了下列隔离级别,Microsoft SQL Server Database Engine支持所有这些隔离级别-->未提交读(隔离事务的最低级别,只能保证不读取物理上损坏的数据)  已提交读(数据库引擎的默认级别)  可重复读  可序列化(隔离事务的最高级别,事务之间完全隔离)
  SQL Server 2005新的隔离级别: SQL Server 2005还支持使用行版本控制的两个事务隔离级别。一个是已提交读隔离的新实现,另一个是新事务隔离级别(快照)。
  行版本控制: 生成触发器中插入的和删除的表。 支持多个活动的结果集(MARS)。 支持指定ONLINE选项的索引操作。 支持基于行版本控制的事务隔离级别-->新实现的已提交读隔离级别,使用行版本控制提供语句级的读取一致性。 新快照隔离级别,提供事务级的读取一致性。 tempdb数据库必须具有足够的空间用于版本存储区。
  读取数据时的行为: 当在基于行版本控制的隔离下运行的事务读取数据时,读取操作不会获取正被读取的数据上的共享锁(S锁),因此不会阻塞正在修改数据的事务。另外,锁定资源的开销随着所获取的锁的数量的减少降至最低。使用行版本控制的已提交读隔离和快照隔离旨在提供副本数据的语句级或事务级读取一致性。
  修改数据时的行为: 在使用行版本控制的已提交读事务中,使用阻塞性扫描(其中读取数据值时将在数据行上采用更新锁(U锁)完成选择要更新的行。这与不使用行版本控制的已提交读事务相同。
                         在快照隔离下运行的事务对数据修改采用乐观方法: 直到数据被修改时才获取数据上的锁。当数据行符合更新标准时,快照事务将验证数据行未被并发事务(在快照事务开始后提交)修改。如果数据行已在快照事务以外修改,则将出现更新冲突,同时快照事务也将终止。更新冲突由数据库引擎处理,无法禁用更新冲突检测。
  设置SQL Server 2005新的隔离级别: 将READ_COMMITED_SNAPSHOT数据库选项设置为ON时,已提交读隔离使用行版本控制提供语句级别的读取一致性。读取操作只需要SCH-S表级别的锁,不需要页锁或行锁。
                                                将READ_COMMITED_SNAPSHOT数据库选项设置为OFF(默认设置)时,已提交读隔离的行为与在SQL Server的早期版本中相同。两个实现都满足已提交读隔离的ANSI定义。
  SQL Server 2005新的隔离级别: 快照隔离级别使用行版本控制来提供事务级别的读取一致性。读取操作不获取页锁或行锁,只获取SCH-S表锁。读取其他事务修改的行时,读取操作将检索启动事务时存在的行的版本。将ALLOW_SNAPSHOT_ISOLATION数据库选项设置为ON时,将启用快照隔离。默认情况下,用户数据库的此选项设置为OFF。
  选择: 对于大多数应用程序,建议应用使用行版本控制的已提交读隔离,而不要应用快照隔离,原因: 已提交读隔离比快照隔离占用的tempdb空间少。已提交读隔离可用于分布式事务,而快照隔离不能用于分布式事务。已提交读隔离可用于大多数现有应用程序,而不需要进行任何更改。快照隔离会发生不适用于使用行版本控制的已提交读隔离的更新冲突。当在快照隔离下运行的事务读取另一个事务稍后会修改的数据时,快照事务对同一数据的更新会导致更新冲突,该事务将终止并回滚。而使用行版本控制的已提交读隔离不存在此问题。
         快照隔离提供事务级读取的一致性。数据快照在快照事务启动时产生并在事务持续时间内保持一致。 发生情况时,使用快照隔离: 需要开放式并发控制。 由于更新冲突必须回滚事务的可能性较低。 应用程序需要基于必须具有时点一致性的长时间运行的多语句查询生成报告。快照隔离具有可重复读取的优点,而不使用共享锁。
  其它技术: 数据库快照  数据库快照是数据库(源数据库)的只读、静态视图。多个快照可以位于一个源数据库中,并且可以作为数据库始终驻留在同一服务器实例上。创建快照时,每个数据库快照在事务上与源数据库一致。在被数据库所有者显示删除之前,快照始终存在。 快照可用于报表。另外,如果源数据库出现用户错误,还可将源数据库恢复到创建快照时的状态。丢失的数据仅限于创建快照后数据库更新的数据。
  数据库快照(Database Snapshot): 数据库某个时间点的快照-->即时创建的 只读性的  基础数据库继续变化-->快照不影响、限制对基础数据库的更新  快照名与基础数据库名不同  返回到以前创建的快照可挽救误操作  极其有效的空间管理  采用"copy on write"机制-->无需复制数据的完整备份  共享无变化的数据库页面  仅存储已变化的数据页  命令-->Create Northwind_SS Update Northwind Read Northwind_SS  结果-->DD
 


本文转自 叶俊生 51CTO博客,原文链接:http://blog.51cto.com/yejunsheng/161364

网友评论

登录后评论
0/500
评论