mvc 高并发解决方案之一---存储过程
MVC用户访问多线程,一般的lock是无法造成单例的。
存储过程既是一种解决方案,先来看看存储过程优缺点:
A、 存储过程允许标准组件式编程
存储过程创建后可以在程序中被多次调用执行,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的提高了程序的可移植性。
B、 存储过程能够实现较快的执行速度
如果某一操作包含大量的T-SQL语句代码,分别被多次执行,那么存储过程要比批处理的执行速度快得多。因为存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的存储计划。而批处理的T-SQL语句每次运行都需要预编译和优化,所以速度就要慢一些。
C、 存储过程减轻网络流量
对于同一个针对数据库对象的操作,如果这一操作所涉及到的T-SQL语句被组织成一存储过程,那么当在客户机上调用该存储过程时,网络中传递的只是该调用语句,否则将会是多条SQL语句。从而减轻了网络流量,降低了网络负载。
D、 存储过程可被作为一种安全机制来充分利用
系统管理员可以对执行的某一个存储过程进行权限限制,从而能够实现对某些数据访问的限制,避免非授权用户对数据的访问,保证数据的安全。
引用地址:http://www.cnblogs.com/hoojo/archive/2011/07/19/2110862.html
再来说说存储过程的事务原理
一、sql事务
1.什么是事务:事务是一个不可分割的工作逻辑单元,在数据库系统上执行并发操作时事务是做为最小的控制单元来使用的。他包含的所有数据库操作命令作为一个整体一起向系提交或撤消,这一组数据库操作命令要么都执行,要么都不执行。
2.事务的语句
开始事物:BEGIN TRANSACTION
提交事物:COMMIT TRANSACTION
回滚事务:ROLLBACK TRANSACTION
3.事务的4个特性
①原子性(Atomicity):事务中的所有元素作为一个整体提交或回滚,是不可折分的,事务是一个完整的操作。
②一致性(Consistemcy):事物完成时,数据必须是一致的,也就是说,和事物开始之前,数据存储中的数据处于一致状态。保证数据的无损。
③隔离性(Isolation):对数据进行修改的多个事务是彼此隔离的。这表明事务必须是独立的,不应该以任何方式来影响其他事务。
④持久性(Durability):事务完成之后,它对于系统的影响是永久的,该修改即使出现系统故障也将一直保留,真实的修改了数据库
4.事务的分类.
按事务的启动与执行方式,可以将事务分为3类:
①显示事务 :也称之为用户定义或用户指定的事务,即可以显式地定义启动和结束的事务。分布式事务属于显示事务
②自动提交事务:默认事务管理模式。如果一个语句成功地完成,则提交该语句;如果遇到错误,则回滚该语句。
③隐性事务:当连接以此模式进行操作时,sql将在提交或回滚当前事务后自动启动新事务。无须描述事务的开始,只需提交或回滚每个事务。它生成连续的事务链。
已事务中的全局变量为基准数,判断@@trancount;
说了这么多,来看看代码
ALTER PROCEDURE [dbo].[GetLottery]AS SET NOCOUNT ON;
declare @trancount int --commit,rollback只控制本存储过程
set @trancount = @@trancount;
if (@trancount=0)
begin tran GetLottery
else
save tran GetLottery *************************************************** if @@Error <> 0
begin
Rollback tran GetLottery
return @id
end
else
begin
commit tran GetLottery
return @id
end
全局@@trancount计数:
执行或者回归都会使计数归零。
最后自行做了测试引用缩写的存储过程发现大并发下并不能完全控制抢占资源问题。
当存储过程执行都在千分之一秒相同的情况下。会造成资源抢占冲突并引起“超发,多发问题”
原理也其实相当简单,数据库支持的时间格式也是千分之一秒。
一下贴出线程测试代码。
public class Threadlist
{
/// <summary>
/// 状态
/// </summary>
public static StaticType Static { get; private set; }
/// <summary>
/// 线程池
/// </summary>
public static List<Thread> Threads { get; set; }
/// <summary>
/// 守护线程
/// </summary>
public static Thread KeeperThread { get; set; }
/// <summary>
/// 结果
/// </summary>
public static List<String> Result { get; set; } public static Int32 CustomerId { get; set; }
static Threadlist()
{
Static = StaticType.StandBy;
Threads = new List<Thread>();
Result = new List<string>();
}
public static void Start()
{
switch (Static)
{
case StaticType.Done://已经完成,相当于重新开始
case StaticType.StandBy://就绪状态
Result = new List<string>();
Threads = new List<Thread>();
Static = StaticType.Running;
for (int i = 0; i < 300; i++)
{
CustomerId = i + 200; Threads.Add(new Thread(delegate() { SqlTest(CustomerId, 14); }));
Threads.Add(new Thread(delegate() { SqlTest(CustomerId, 15); }));
Threads[i].Start();
}
KeeperThread = new Thread(new ThreadStart(Keeper));
KeeperThread.Start();
break;
default:
break;
} } private static void Keeper()
{
while (Static == StaticType.Running)
{
Thread.Sleep(500);
if (!Threads.Any(t => t.IsAlive))//作业全部完成
Static = StaticType.Done;
}
} public enum StaticType
{
StandBy,
Running,
Done
}
public static void SqlTest(Int32 CustomerId, Int32 CommodityId)
{
var db = new WebDatabase();
var Code = Guid.NewGuid().ToString();var lottery = db.EventLotteryHistories.FirstOrDefault(x => x.BonusId == null);
var Type = 0;
var PayCount = 1;
var sqlstatue = 0;
var orderId = 0;
while (sqlstatue==0)
{
sqlstatue = 1;
try
{ var lotteryId = new SqlParameter { ParameterName = "LotteryHistoryId", Value = lottery.Id, Direction = ParameterDirection.Input };
var result = new SqlParameter { ParameterName = "id", Value = 0, Direction = ParameterDirection.Output };
db.Database.ExecuteSqlCommand(System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction,
"exec @id = GetLottery @LotteryHistoryId", lotteryId, result);
//////////////////////////增加错误捕获代码///////////////////////////////
var statue = result.Value;
Result.Add(CustomerId.ToString() + "... " + statue.ToString());
}
catch (Exception)
{
sqlstatue = 0;
}
}
}
}
}
之前在使用ef调用存储过程中遇到了卡了一天的一个坑。
ef直接调用存储过程中会在外壳添加一个事务循环,以此来判断事务是否正确运行。
但是如果在调用事务中原本就有事务导致冲突,因此调用时请选择事务状态:“不执行事务模式”---“System.Data.Entity.TransactionalBehavior.DoNotEnsureTransaction”
mvc 高并发解决方案之一---存储过程的更多相关文章
- 关于SQL SERVER高并发解决方案
现在大家都比较关心的问题就是在多用户高并发的情况下,如何开发系统,这对我们程序员来说,确实是值得研究,最近找工作面试时也经常被问到,其实我早有去关心和了解这类问题,但一直没有总结一下,导致面试时无法很 ...
- PHP面试(二):程序设计、框架基础知识、算法与数据结构、高并发解决方案类
一.程序设计 1.设计功能系统——数据表设计.数据表创建语句.连接数据库的方式.编码能力 二.框架基础知识 1.MVC框架基本原理——原理.常见框架.单一入口的工作原理.模板引擎的理解 2.常见框架的 ...
- 手把手让你实现开源企业级web高并发解决方案(lvs+heartbeat+varnish+nginx+eAccelerator+memcached)
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://freeze.blog.51cto.com/1846439/677348 此文凝聚 ...
- java并发编程与高并发解决方案
下面是我对java并发编程与高并发解决方案的学习总结: 1.并发编程的基础 2.线程安全—可见性和有序性 3.线程安全—原子性 4.安全发布对象—单例模式 5.不可变对象 6.线程封闭 7.线程不安全 ...
- 高并发解决方案--负载均衡(HTTP,DNS,反向代理服务器)(解决大流量,高并发)
高并发解决方案--负载均衡(HTTP,DNS,反向代理服务器)(解决大流量,高并发) 一.总结 1.什么是负载均衡:当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能.那么,在服 ...
- JAVA系统架构高并发解决方案 分布式缓存 分布式事务解决方案
JAVA系统架构高并发解决方案 分布式缓存 分布式事务解决方案
- Java分布式系统高并发解决方案
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
- java 高并发解决方案
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
- Java--分布式系统高并发解决方案
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
随机推荐
- appstore 上传需要的icon
<key>CFBundleIconFiles</key><array> <string>icon@2x.png</string> <s ...
- Py修行路 python基础 (十五)面向对象编程 继承 组合 接口和抽象类
一.前提回忆: 1.类是用来描述某一类的事物,类的对象就是这一类事物中的一个个体.是事物就要有属性,属性分为 1:数据属性:就是变量 2:函数属性:就是函数,在面向对象里通常称为方法 注意:类和对象均 ...
- python's ninth day for me
函数 函数的定义与调用: #def 关键字 定义一个函数. # my_len 函数名, 函数名的书写规则与变量的命名一致. # def 与函数名中间一个空格. # 函数名() : 加上冒号. ...
- PCA主成分分析 ICA独立成分分析 LDA线性判别分析 SVD性质
机器学习(8) -- 降维 核心思想:将数据沿方差最大方向投影,数据更易于区分 简而言之:PCA算法其表现形式是降维,同时也是一种特征融合算法. 对于正交属性空间(对2维空间即为直角坐标系)中的样本点 ...
- html 之表单,div标签等
一 , 表单 功能 : 表单用于向服务器传输数据, 从而实现用户与Web服务器的交互 表单能够包含input系列标签,比如文本字段,复选框 , 单选框 , 提交按钮等等. 表单还可以包含textare ...
- The centos disc was not found in any of your drives.Please insert the centos disc and press OK to retry
查看虚拟机设置中关于CDROM的选项,将CDROM的状态改为已连接,不要奇怪,勾选上之后再按下OK就好了
- Java虚拟机(四):常用JVM配置参数
一.VM选项 - : 标准VM选项,VM规范的选项 -X: 非标准VM选项,不保证所有VM支持 -XX: 高级选项,高级特性,但属于不稳定的选项 参见Java HotSpot VM Options 二 ...
- 安装saltstack-web管理界面
1.安装salt-master.salt-minion和salt-api $ sudo yum install epel-release -y $ sudo yum install salt-mast ...
- Xcode迁移工程常见问题
[Xcode迁移工程常见问题] 1.Header Search Paths (HEADER_SEARCH_PATHS) 是否设置正确.在Search Paths group下. 2.Framework ...
- java基础之多线程五:实现Runnable的原理
实现Runnable接口的原理. 背景: 多线程的第一种实现方式是::继承Thread类, 因为我们自定义的类(MyThread)是Thread类的子类, 所以MyThread类的对象调用start( ...