LINQ学习之旅——第二站"LTQ"之并发访问冲突及处理
2011-09-16 23:05
197 查看
在编写用户应用软件时,只要是涉及到数据库的操作,尤其是对于多用户并发访问数据库的情况,开发人员都要考虑如何来解决并发冲突的问题。当一个用户从数据库中读取数据并修改数据,最后把修改结果保存到数据库中,在这个过程中,另外一个用户也同样在查询和修改和上一个用户相同的数据,并早于上一个用户向数据库提交了更改,这时第一个用户在向数据库提交修改就发生了所谓的并发冲突。所以所开发的程序一定要提供对并发冲突检测和处理的机制。一般情况下,处理并发冲突有两种方式:乐观并发和悲观并发。下面详细介绍一下这两种处理并发冲突的方式。
1.乐观并发:
从字面意思上来看,就是说它对于并发冲突的发生持有乐观的态度,且认为大部分的程序运行时间里不会发生并发冲突。所以程序在访问和修改数据库时不会锁定要修改的数据,而是采用一种在修改时动态监测并发冲突的可能性的方法。乐观并发允许大量的用户访问数据库,也是目前应用最广泛的一种并发冲突处理方式。而LINQ TO SQL就提供了对乐观并发的支持,来帮助完成冲突检测和冲突处理任务。LINQ TO SQL提供了两种方法来检测并发冲突。这两种方式关键都在之前对象——关心映射(ORM)一节中所提到的内联属性Column中参数IsVersion和UpdateCheck的设置上。那么第一种就是用参数IsVersion来修饰实体类的列属性,如果实体类的某一列使用了IsVersion修饰并其值设置为true,这该列用于检测并发冲突。在用示例进一步说明之前,先把前几节都用到过的实体类Student做如下更改:
事务处理避免并发冲突
ii.结果:
原因在于事务1将数据库中数据锁住,进行数据修改,但并未提交事务,所以导致事务2一直等待事务1结束,而事务1的结束必须要等事务2结束,所以事务2不可能会有机会来执行,所以事务2最终等待超时抛出异常。
1.乐观并发:
从字面意思上来看,就是说它对于并发冲突的发生持有乐观的态度,且认为大部分的程序运行时间里不会发生并发冲突。所以程序在访问和修改数据库时不会锁定要修改的数据,而是采用一种在修改时动态监测并发冲突的可能性的方法。乐观并发允许大量的用户访问数据库,也是目前应用最广泛的一种并发冲突处理方式。而LINQ TO SQL就提供了对乐观并发的支持,来帮助完成冲突检测和冲突处理任务。LINQ TO SQL提供了两种方法来检测并发冲突。这两种方式关键都在之前对象——关心映射(ORM)一节中所提到的内联属性Column中参数IsVersion和UpdateCheck的设置上。那么第一种就是用参数IsVersion来修饰实体类的列属性,如果实体类的某一列使用了IsVersion修饰并其值设置为true,这该列用于检测并发冲突。在用示例进一步说明之前,先把前几节都用到过的实体类Student做如下更改:
事务处理避免并发冲突
staticvoid Main(string[] args) { string str_conn =@"Data Source=localhost;Initial Catalog=DB_Student;User ID=sa;Password=king"; DataContext dc =new DataContext(str_conn); //使用事务将数据库中的记录锁定 using (TransactionScope t1 =new TransactionScope()) { var students = dc.GetTable<Student>(); var student = (from stu in students where stu.Name =="刘麻子" select stu).Single(); //修改实体类对象 student.Name ="张麻子"; //模拟并发访问 using (TransactionScope t2 =new TransactionScope(TransactionScopeOption.RequiresNew)) { SqlConnection conn =new SqlConnection(str_conn); SqlCommand cmd = conn.CreateCommand(); cmd.CommandText ="update student set sname='刘晓光' where sname='刘麻子'"; cmd.CommandType = System.Data.CommandType.Text; conn.Open(); cmd.ExecuteNonQuery(); conn.Close(); //事务2提交 t2.Complete(); } //提交数据修改到数据库 dc.SubmitChanges(); //事务1提交 t1.Complete(); } Console.Read(); }
ii.结果:
原因在于事务1将数据库中数据锁住,进行数据修改,但并未提交事务,所以导致事务2一直等待事务1结束,而事务1的结束必须要等事务2结束,所以事务2不可能会有机会来执行,所以事务2最终等待超时抛出异常。
相关文章推荐
- LINQ学习之旅——第二站"LTQ"之标准数据库操作(增查删改)
- Linq to Sql : 并发冲突及处理策略
- Linq to Sql : 并发冲突及处理策略
- Linq to Sql : 并发冲突及处理策略
- Linq to Sql : 并发冲突及处理策略
- Linq to Sql : 并发冲突及处理策略
- 并发处理 - 配置文件"并发:报表访问层"的设置 (Doc ID 1625757.1)
- Linq to Sql并发冲突及处理策略
- 批处理学习笔记7 - 管道连接符"|"
- 0x00000000 处有未经处理的异常: 0xC0000005: 在位置 0x0000000000000000 发生访问冲突
- 学习linq处理数据
- 有未经处理的异常: 0xC0000005: 写入位置 0x01260000 时发生访问冲突
- (转载)0x0F1AFD76 (libcocos2d.dll) (Plane.exe 中)处有未经处理的异常: 0xC0000005: 读取位置 0x00000018 时发生访问冲突。
- 这是一个秒杀系统,即大量用户抢有限的商品,先到先得 用户并发访问流量非常大,需要分布式的机器集群处理请求 系统实现使用Java
- Android NDK学习 <六> 复杂结构动态库处理和第三方库的移植
- php如何处理html5表单<input type="file" multiple />提交的多个文
- SQL0902C 发生错误<原因码 = "">。无法处理后续的SQL语句。 SQLSTATE=58005
- 在Linq to Sql中管理并发更新时的冲突(1):预备知识
- Silverlight点滴(四)Silverlight访问Web Service报"System.Security.SecurityException: 安全性错误"的处理
- 【vs调试】C/C++ 错误处理(文档):未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突