SqlServer性能优化 提高并发性能二(九)
补充上一篇修改用非聚集索引:
update Employee set age=age+1 from Employee with(index=nc_Employee_Age) where age<30
执行计划:

并发访问控制隔离级别:
1.读提交:默认行为,读取时请求S锁
set transaction isolation level read committed
select * from Employee where age=34
2. 脏读:读取时不请求S锁,不会受到其他X锁限制
set transaction isolation level read uncommitted
select * from Employee
3. 已提交快照读:更新时将老的数据复制到 Tempdb:read_committed_snapshot
alter database HRDB
set read_committed_snapshot on
设置成单用户模式:

设置事物:
begin tran
update Employee set age=age+1 where age>=30
执行语句:
select * from Employee

这条语句也可以执行:
select * from Employee where age>30
这条可以执行:
update Employee set age=age+1 from Employee with(index=nc_Employee_Age) where age<30
没有复制的还是从索引或基表中读取。所以可以读取出数据
这条不能执行:
update Employee set age=age+1 from Employee with(index=nc_Employee_Age) where age>30
打开数据库的读提交快照。 对记录进行操作时,会把排他锁的数据放到Tempdb数据库中,访问的时候直接读出Tempdb的数据。
4.可重复读:事物结束前,不释放获取的S锁,可能会形成死锁
create table Products(id int identity(1,1),name varchar(500),UnitPrice money) delete from Products where id=2
insert Products values ('p1',13)
insert Products values('p2',5) --业务逻辑:单价大于10的优惠10
begin tran
declare @UnitPrice money
set @UnitPrice=(select @UnitPrice from Products where id=1) --执行等待的时间
waitfor delay '00:00:20'
if @UnitPrice>10
update Products set UnitPrice=UnitPrice-10 where id=1
commit tran
第二个人执行打六折的业务:
update Products set UnitPrice=UnitPrice*0.6
结果:

事务中尽量不要放查询语句:13*0.6=7.8 7.8-10=-2.2
实在要查询语句,如何解决呢?
删除上述表:drop table Products 重新创建
1. --在开启事务之前 设置事务的级别 可重复读
--在开启事务之前 设置事务的级别 可重复读
set transaction isolation level repeatable read
--业务逻辑:单价大于10的优惠10
begin tran
declare @UnitPrice money
set @UnitPrice=(select @UnitPrice from Products where id=1) --执行等待的时间
waitfor delay '00:00:20'
if @UnitPrice>10
update Products set UnitPrice=UnitPrice-10 where id=1
commit tran
2.打六折:
update Products set UnitPrice=UnitPrice*0.6
结果:

with(updlock) 可重复读的方式 可以保护线程。代码如下:
begin tran
declare @UnitPrice money
set @UnitPrice=(select @UnitPrice from Products with(updlock) where id=1) --执行等待的时间
waitfor delay '00:00:20'
if @UnitPrice>10
update Products set UnitPrice=UnitPrice-10 where id=1
commit tran update Products set UnitPrice=UnitPrice*0.6

5. 串行化:访问的行和按顺序下一行放置范围锁,防止不必要操作与插入数据
业务背景:给分组为:‘group1’的员工发奖金,加入了新的员工
create table Employees(id int identity(1,1),name varchar(500),groups varchar(500),salary money)
insert Employees values('caojian','grouup1',3000)
insert Employees values('ligang','grouup1',1000)
insert Employees values('huang','grouup2',1500)
insert Employees values('sunliyuan','grouup2',2000)
业务逻辑的事务语句:
begin tran
declare @count int
set @count=(select COUNT(*) from Employees where groups='grouup1')
declare @avgsalary money
set @avgsalary=20000/@count waitfor delay '00:00:20'
update Employees set salary=salary+@avgsalary where groups='grouup1'
commit tran
第二个线程执行的语句:
insert Employees values ('newemployee','grouup1',0)
这种结果是不对的:

--设置串行化
set transaction isolation level serializable
begin tran
declare @count int
set @count=(select COUNT(*) from Employees where groups='grouup1')
declare @avgsalary money
set @avgsalary=20000/@count waitfor delay '00:00:20'
update Employees set salary=salary+@avgsalary where groups='grouup1'
commit tran
进行添加:
insert Employees values ('newemployee','grouup1',0)
执行查询语句:

针对group创建索引:
--针对group创建聚集索引
create clustered index c_Employees_group on Employees (groups)
执行事务:
--设置串行化
set transaction isolation level serializable
begin tran
declare @count int
set @count=(select COUNT(*) from Employees where groups='grouup1')
declare @avgsalary money
set @avgsalary=20000/@count waitfor delay '00:00:20'
update Employees set salary=salary+@avgsalary where groups='grouup1'
commit tran
执行以下三条语句:
insert Employees values ('newemployee','grouup1',0)
insert Employees values ('newemployee','grouup2',0)
insert Employees values ('newemployee','grouup3',0)
grouup1有影响,grouup2和grouup3无影响。

6. 快照:比已提交快照读取更严格,试图对修改数据应用X(排他锁),如果已发生改变,事物失败 allow_snapshot_isolation
创建表:
create table SnapShotTB(id int identity(1,1),name varchar(500),age int)
insert SnapShotTB values('caojian',33)
给数据库进行配置:
--打开配置数据库的一个选项
alter database HRDB
--允许快照隔离
set allow_snapshot_isolation on
设置事物的隔离级别:
--设置事物的隔离级别为快照
set transaction isolation level snapshot
begin transaction
declare @age int
set @age=(select age from SnapShotTB where name='caojian')
waitfor delay '00:00:20'
update SnapShotTB set age =age+1 where name='caojian'
commit tran
第二个线程:
update SnapShotTB set age =age-1 where name='caojian'
报的错误:
减少阻塞与死锁的建议:
1.合适的索引
2.合适的分区
3.调整合适的隔离级别
4.查询条件的有限性
5.相同的顺序操作资源
6.短的事务
.NET 调用的案例:(EF CodeFirst)
1.连上数据库。
2.引入命名空间。

3.在领域层引入命名空间:
using System.Transactions;
using System.Data;
using System.Linq;
4.代码:
/// <summary>
/// 奖金处理的业务
/// </summary>
public void ProcessSalary()
{
TransactionOptions option = new TransactionOptions();
//指定的隔离级别(串行化)
option.IsolationLevel = System.Transactions.IsolationLevel.Serializable;
using (TransactionScope scope=new TransactionScope(TransactionScopeOption.Required,option))
{
//连到数据访问的上下文
HRUser dbcontext = new HRUser();
var employees = dbcontext.Set<Employees>().Where(p => p.groups == "grouup1").ToList();
//取得groupp1组的人数
int count = employees.Count;
//把奖金进行employees平分
decimal salary = 20000 / count;
//对每个人的值进行跟新
foreach (var emoloyee in employees)
{
dbcontext.Set<Employees>().Attach(emoloyee);
//状态是可修改的
dbcontext.Entry<Employees>(emoloyee).State = System.Data.Entity.EntityState.Modified;
emoloyee.salary = emoloyee.salary + salary;
}
dbcontext.SaveChanges();
//事物的完成
scope.Complete();
}
}
调用:
protected void Button1_Click(object sender, EventArgs e)
{
Employees es = new Employees();
es.ProcessSalary();
}
点击button数据库更新成功。
7. 索引对隔离级别的影响、阻塞的监视
SqlServer性能优化 提高并发性能二(九)的更多相关文章
- SqlServer性能优化 提高并发性能(八)
并发访问: 当多个线程访问同一个资源,会产生并发性问题 并发控制与处理: 乐观并发控制:一种方式是"后来的更新者获胜" 这意味着先来的用户提交的值会在没有察觉的情况下丢失. 为 ...
- 性能优化——Web前端性能优化
核心知识点: 1.排查网站性能瓶颈的手法:分析各个环节的日志,找出异常部分 2.Web前端:网站业务逻辑之前的部分(浏览器.图片服务.CDN) 3.优化手段 1)浏览器优化 (1)减少http请求 a ...
- Android App性能优化笔记之一:性能优化是什么及为什么?
By Long Luo 周星驰的电影<功夫>里面借火云邪神之口说出了一句至理名言:“天下武功,唯快不破”. 在移动互联网时代,同样如此,留给一个公司的窗口往往只有很短的时间,如何把握住 ...
- 微擎开启性能优化里面的性能优化memcache内存优化及数据库读写分离
http://www.mitusky.com/forum.php?mod=viewthread&tid=3135 [微擎 安装使用] 微擎开启性能优化里面的性能优化memcache内存优化及数 ...
- nginx配置优化提高并发量
1 nginx配置优化提高并发量 worker_processes 2; 这个按照CPU的核数来决定 2 worker_connections 65535; 这个一般设置65535即可 每个进程允许的 ...
- web性能优化-网络传输性能优化
浏览器工作原理:https://www.cnblogs.com/thonrt/p/10008220.html 浏览器渲染原理: https://www.cnblogs.com/thonrt/p/100 ...
- Web前端性能优化——提高页面加载速度
前言: 在同样的网络环境下,两个同样能满足你的需求的网站,一个“Duang”的一下就加载出来了,一个纠结了半天才出来,你会选择哪个?研究表明:用户最满意的打开网页时间是2-5秒,如果等待超过10秒, ...
- JVM性能优化,提高Java的伸缩性
很多程序员在解决JVM性能问题的时候,花开了很多时间去调优应用程序级别的性能瓶颈,当你读完这本系列文章之后你会发现我可能更加系统地看待这类的问题.我说过JVM的自身技术限制了Java企业级应用的伸缩性 ...
- SQL Server查询性能优化——覆盖索引(二)
在SQL Server 查询性能优化——覆盖索引(一)中讲了覆盖索引的一些理论. 本文将具体讲一下使用不同索引对查询性能的影响. 下面通过实例,来查看不同的索引结构,如聚集索引.非聚集索引.组合索引等 ...
随机推荐
- 并发编程 01—— ThreadLocal
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- Javascript学习笔记2.2 Javascript与DOM选项卡(滑动门)案例详解
学习了DOM的知识,今天开始做些练习,想到了一个网页滑动门的特效,见下图: 1.通过建立索引实现 <!doctype html> <html> <head> < ...
- ThinkPHP 3.2.3(二)配置
一.配置格式 1.PHP数组定义 默认所有配置文件的定义格式均采用返回PHP数组的方式,配置参数不区分大小写. 如果使用二维数组来配置更多的信息,则二级参数配置区分大小写.格式为: //项目配置文件r ...
- Java项目:学生成绩管理系统(一)
学生成绩管理系统(一) 项目名称:学生成绩管理系统 项目需求分析(Need 需求): (1)该系统的用户分为教师和学生.教师的功能有:管理某一学生或课程的信息以及成绩,包括增.删.查.报表打印等:学生 ...
- [原创]在Linux系统Ubuntu14.04上安装部署docker。
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何 ...
- 多项目开发下的dll文件管理
阅读目录: DS01:为什么要对生成的dll文件进行管理? DS02:首先介绍以下两个DOS命令 DS03:第一种实现方法(xcopy) DS04:第二种实现方法(attrib) DS05:分享一个有 ...
- 【Python④】python恼人的字符串,格式化输出
恼人的字符串 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.由于计算机是美国人发明的,因此,最早只有127个字母被编码到计算机里,也就是大小写英文字母.数字和一些符号,这个编码 ...
- Emoji表情符号录入MySQL数据库失败解决
让MySQL支持Emoji表情,涉及无线相关的 MySQL 数据库建议都提前采用 utf8mb4 字符集. utf8mb4和utf8到底有什么区别呢?原来以往的mysql的utf8一个字符最多3字节, ...
- jQuery LigerUI V1.2.3 (包括API和全部源码) 发布
前言 这次版本主要是增加了Panel和Portal组件,并增加了一套皮肤,并解决了部分兼容性的问题,添加了几个功能点. 欢迎使用反馈. 相关链接 API: http://api.lig ...
- 用JQuery Validate框架,在IE8下验证报错问题解决
网站后台用了JQuery Validate框架,版本是jQuery Validation Plugin 1.8.1 因为用的时间比较久了,一直没有更新新版本. 最近公司信息录入员有调整,没有IE11浏 ...