离线并发:各种支持多线程多数据库事务的应用服务器1.并发问题:1)丢失更新(同时编辑文件,一个接一个保存,最后丢失更新的内容第一个saver)2)不一致2.执行上下文:1)从与外界交互的角度来看有两个上下文:request:对应于软件工作的外部环境发出的单一调用,以及处理请求的软件会决定是否返回响应(大部分过程在服务器端执行,假设客户端正在等待响应)session:客户端和服务器之间的长时间交互2)操作系统的2个上下文:process:重量级执行上下文,将它正在处理的内部数据域与外界隔离开来(有效隔离,减少冲突,但资源消耗大)Thread:lightwe正确的执行上下文,单个进程中可以有多个线程(可以充分利用资源,但容易导致并发问题)3.隔离性和不变性:企业应用的2种解决方案:1)隔离性:解决方案1:划分数据使得每条数据只能被一个执行单元访问(操作系统为每个进程单独分配一块内存,只有本进程才能读写这块内存)方案二:文件锁,一个人打开文件,其他人不能再打开或者只能打开文件的只读副本,并且不能修改(一个好的并发设计应该是:想方设法创建隔离区,保证尽可能多的任务可以在每个隔离区完成)2)不变性:解决方案1:识别什么是不变数据(并发问题只有在共享数据可以修改的情况下才会出现),不考虑这些数据的并发问题2广泛分享解决方案ion2:把只读数据的程序分开,让他们只使用副本数据源4.乐观并发控制和悲观并发控制:1)2种锁:乐观锁:关于冲突检测(只有当updateissubmitted)优点:并发度高,限制少,使用相对自由缺点:业务数据复杂,难以自动合并,当用户难以发现差异时,只能舍弃原有数据并从头更新悲观锁:关于避免冲突(只要有人已经在使用当前数据或文件,就拒绝其他人使用当前数据或文件)优点:降低并发度缺点:用户体验差两种策略选择标准:冲突频率和严重程度(当冲突较少或冲突后果不严重时,选择乐观锁;否则选择悲观锁)2)避免不一致性能:a。检测不一致读:悲观策略:通过读锁(读锁、共享锁)和写锁(写锁、排他锁),多人可以同时对同一份数据加只读锁,但只要有人加过一次获得了只读锁,其他人无法获得写锁;一旦有人获得写锁,其他人就无法获得这两种乐观策略中的任何一种。略:根据数据的某个版本标识(时间戳或序列计数器),检查待更新数据的版本标识和共享数据的版本标识。如果两者相同,则系统允许数据更新,并更新共享数据的版本标识。b.定时读取:每次读取数据时,以某种时间戳或其他常量标签作为约束,数据库根据时间或标签返回数据(可以使用源码控制软件,但数据库比较难且昂贵)3)死锁:处理死锁的方法:a.用软件检测死锁的发生,选择一个受害者,放弃他的工作和他加的锁;b.为每个锁添加时间限制,一旦达到时间限制,添加的锁将失效,工作将丢失;防止死锁的方法:强制人们在开始工作时获得所有可能的锁,之后不允许再有锁;可以hard指定每个人获取锁的顺序(比如按名字字母顺序)5.事务:1)ACID:Atomicity,Consistency,Isolation,Persistence2)事务资源:定义:任何可以进行事务处理的事务控制method:保证事务尽可能短(尽量不要让事务跨越多个请求,跨越多个请求的事务称为长事务);尽量晚开启事务3)降低事务隔离度,提高灵活性:SQL的4个隔离级别:Serializable,repeatableread,readcommitted,readuncommitted不必为所有事务设置相同的隔离级别,但应该仔细观察每一个事务并决定如何权衡灵活性和正确性4)业务事务和系统事务:系统事务:关系数据库系统和事务监视器支持的事务(一般无需干预)业务事务:简单方法:在单个系统事务中执行完整的业务事务(生成长系统事务);复杂,使用离线并发(通过工作单元保存更新数据)6.离线并发控制方式:乐观离线锁,悲观离线锁7.应用服务器并发:一个线程一个会话VS一个进程一个会话:线程节省资源,但创建进入隔离区很重要
