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 高并发解决方案之一---存储过程的更多相关文章

  1. 关于SQL SERVER高并发解决方案

    现在大家都比较关心的问题就是在多用户高并发的情况下,如何开发系统,这对我们程序员来说,确实是值得研究,最近找工作面试时也经常被问到,其实我早有去关心和了解这类问题,但一直没有总结一下,导致面试时无法很 ...

  2. PHP面试(二):程序设计、框架基础知识、算法与数据结构、高并发解决方案类

    一.程序设计 1.设计功能系统——数据表设计.数据表创建语句.连接数据库的方式.编码能力 二.框架基础知识 1.MVC框架基本原理——原理.常见框架.单一入口的工作原理.模板引擎的理解 2.常见框架的 ...

  3. 手把手让你实现开源企业级web高并发解决方案(lvs+heartbeat+varnish+nginx+eAccelerator+memcached)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://freeze.blog.51cto.com/1846439/677348 此文凝聚 ...

  4. java并发编程与高并发解决方案

    下面是我对java并发编程与高并发解决方案的学习总结: 1.并发编程的基础 2.线程安全—可见性和有序性 3.线程安全—原子性 4.安全发布对象—单例模式 5.不可变对象 6.线程封闭 7.线程不安全 ...

  5. 高并发解决方案--负载均衡(HTTP,DNS,反向代理服务器)(解决大流量,高并发)

    高并发解决方案--负载均衡(HTTP,DNS,反向代理服务器)(解决大流量,高并发) 一.总结 1.什么是负载均衡:当一台服务器的性能达到极限时,我们可以使用服务器集群来提高网站的整体性能.那么,在服 ...

  6. JAVA系统架构高并发解决方案 分布式缓存 分布式事务解决方案

    JAVA系统架构高并发解决方案 分布式缓存 分布式事务解决方案

  7. Java分布式系统高并发解决方案

    对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...

  8. java 高并发解决方案

    对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...

  9. Java--分布式系统高并发解决方案

    对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...

随机推荐

  1. Qt WebRTC demo

    This is a very simple demonstration of how to stream from a native application to the browser using ...

  2. Lagom production deployment

    tutorial:https://developer.lightbend.com/guides/lagom-kubernetes-k8s-deploy-microservices/ 一.harbor ...

  3. 给安卓端调用的apk、图片下载接口

    package com.js.ai.modules.pointwall.action; import java.io.File; import java.io.FileInputStream; imp ...

  4. AngryFuzz3r-web扫描工具

    项目地址:https://github.com/ihebski/angryFuzzer 下载完后打开文件 安装一下所需的Python模块 root@sch01ar:/sch01ar/angryFuzz ...

  5. Apache rewrite 出现 400 Bad Request 的解决方法

    <VirtualHost *:80 *:81>         ServerAdmin deng5765@163.com         DocumentRoot /active/www/ ...

  6. 简单 JS 弹出层 背景变暗

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 查看自己U盘格式

    转自:https://zhidao.baidu.com/question/220844418.html 选中U盘后,鼠标右键单击,选项菜单中点击属性,出的的属性窗口中的“常规”项里边就有U盘的基本信息 ...

  8. C++加载位图跟SOCKET通信的编写

    //将屏幕信息转换为位图结构 CDC *pDeskDC=GetDesktopWindow()->GetDC();//获取桌面的额画图对象 ; ; CDC memDC;//定义一个内存画布 mem ...

  9. rdlc设置指定列隐藏

    此用户帐户对提案名称列不可见

  10. Nginx静态网站的部署

    静态网站的部署 首先先看一下nginx/conf/nginx.conf 配置文件内的信息: #user nobody; worker_processes 1; #error_log logs/erro ...