不用锁表,没有异常:在高并发网络中高效的更新数据库数据的方式
2009-08-10 12:18
423 查看
很多Web系统的瓶颈在网络IO,所以很多系统都采用多Web服务器负载均衡,双DB做双机热备(其实就是只有一个DB,两台只有一台真正工作,死掉一台另一台顶上)的方式部署,在这个时候很多原本不是问题的系统也会产生很多的问题。
这里我们假设有表Product,其定义如下:
列明 | 类型 | 说明 |
Id | Int | 自增字段,实例的ID |
ProductName | Varchar(100) | 商品的名称 |
StoreCount | int | 库存数量 |
。。。 | 。。。 | 。。。 |
如果我们采用数据库锁可以避免这个问题,但是随之而来的是系统效率降低和无可避免的异常,而hibernate等实现的乐观锁呢,呵呵,对不起了,在多Web服务器的时候还能起作用吗?
由此产生了以下的解决方案:
和乐观锁的实现相反,我们不反对任何一个客户端的提交,乐观锁对读取的数据增加版本号,那么这个解决方案中对提交的数据增加“版本号”其实也就是时间戳。针对上面的Product表作为例子,为了实现无锁的提交,我们需要增加一个表Product_Dirty,以后我们将称其为脏表,Product表我们称之为主表。脏表的结构和主表几乎完全一致,只是增加了一个时间戳字段用于记录详细的插入时间:
列明 | 类型 | 说明 |
Timespan | Int | 时间戳,精确到毫秒(能到纳秒更好) |
Id | Int | 实例的ID(这里就不是自增字段了) |
ProductName | Varchar(100) | 商品的名称 |
StoreCount | int | 库存数量 |
。。。 | 。。。 | 。。。 |
此解决方案来自电信营帐系统的设计,由于省电信众多系统都是由分布很广的地市州电信业务人员操作,所以修改的时候经常存在本文要解决的问题,由于操作的人多,锁表的话会造成严重的拥塞,故产生了这个解决方案,由于电信的业务需要后台跑了一个服务来合并数据,并且每秒定时运行,故每秒为一个业务周期。我将其修改成在读取的时候合并,更加灵活一些。
好处:不用锁表,乐观锁也不用,可以在N多服务器操作的时候使用,且大家都不会报错,简化了异常处理。
坏处:增加了表,结构复杂,如果是用于修改原有业务如果只是几个关键表的话还好,全部都采用这个方式工作量巨大(好在电信不缺钱)。
弱点:和乐观锁类似,在某些场景下仍然可能脏读,所以如果对这方面有很高的要求,还是用悲观锁吧。
相关文章推荐
- 不用锁表,没有异常:在高并发网络中高效的更新数据库数据的方式<转>
- 不用锁表,没有异常:在高并发网络中高效的更新数据库数据的方式
- 高并发网站更新数据库数据比较高效的方式
- 高并发网站更新数据库数据比较高效的方式
- 高并发网站更新数据库数据比较高效的方式
- 通过试验探索Access 2000/XP 数据库的最佳 NTFS 权限设置Microsoft Jet 数据库引擎打不开文件'D:\wwwroot\test\data\'。 它已经被别的用户以独占方式打开,或没有查看数据的权限。
- 将B表数据更新到A表中不同数据库的实现方式。
- Microsoft Jet 数据库引擎打不开文件,它已经被别的用户以独占方式打开,或没有查看数据的权限。
- 索引是从数据库中获取数据的最高效方式之一。95%的数据库性能问题都可以采用索引技术得到解决。
- 对于分页时,若数据库的数据不断更新,不让前台显示脏数据(同一条数据重复显示)的处理方式
- 数据库数据更新,不同表,不同数据库的更新方式
- FMDB性能优化问题。使用FMDB事务批量更新数据库速度问题。(亲测可以呀---740条数据用和不用事务效率差别20倍+)
- Visual C# 2008+SQL Server 2005 数据库与网络开发--8.2.2 用户数据操作的并发
- EF更新数据库报错:初始化数据库时发生异常。有关详细信息
- ACCESS"数据库提示它已经被别的用户以独占方式打开,或没有查看数据的权限"的问题
- 关于Microsoft Access数据库错误 '80004005',“已经被别的用户以独占方式打开,或没有查看数据的权限。”
- 并发数据库事务缺锁导致的数据不一致情况:丢失更新,脏读,不可重复读,幻读
- ACCESS"数据库提示它已经被别的用户以独占方式打开,或没有查看数据的权限"的问题
- 不用Map高效更新数据对应关系
- 当读取数据,而未将处理后的数据提交会数据库时,如果数据库发上更改,将会引发LINQ异常,处理方式有: