<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns="http://purl.org/rss/1.0/">
<channel rdf:about="http://www.4vsky.com">
<title>星际浪子</title>
<link>http://www.4vsky.com</link>
<description>星际浪子</description>
<dc:language>zh-cn</dc:language>
<dc:creator>webmaster@loveyuki.com</dc:creator>
<items>
<rdf:Seq>
<item rdf:about="http://www.4vsky.com/blogview.asp?logID=35"><title><![CDATA[用C#实现HTTP协议下的多线程文件传输]]></title><description><![CDATA[很多人都有过使用网络蚂蚁或网络快车软件下载互联网文件的经历，这些软件的使用可以大大加速互联网上文件的传输速度，减少文件传输的时间。这些软件为什么有如此大的魔力呢？其主要原因是这些软件都采用了多线程下载和断点续传技术。如果我们自己来编写一个类似这样的程序，也能够快速的在互联网上下载文件，那一定是非常愉快的事情。下面我就讲一讲如何利用C#语言编写一个支持多线程下载文件的程序，你会看到利用C#语言编写网络应程序是多么的容易，从中也能体会到C#语言中强大的网络功能。<br><br>　　首先介绍一下HTTP协议，HTTP&nbsp;亦即Hpyer&nbsp;Text&nbsp;Transfer&nbsp;Protocal的缩写，它是现代互联网上最重要的一种网络协议，超文本传输协议位于TCP/IP协议的应用层，是一个面向无连接、简单、快速的C/S结构的协议。HTTP的工作过程大体上分连接、请求、响应和断开连接四个步骤。C#语言对HTTP协议提供了良好的支持，在.NET类库中提供了&nbsp;WebRequest和WebResponse类，这两个类都包含在System.Net命名空间中，利用这两个类可以实现很多高级的网络功能，本文中多线程文件下载就是利用这两个类实现的。&nbsp;WebRequest和WebResponse都是抽象基类，因此在程序中不能直接作为对象使用，必须被继承，实际使用中，可根据URI参数中的URI前缀选用它们合适的子类，对于HTTP这类URI,HttpWebRequest和HttpWebResponse类可以用于处理客户程序同WEB服务器之间的HTTP通讯。<br><br>　　HttpWebRequest类实现了很多通过HTTP访问WEB服务器上文件的高级功能。HttpWebRequest&nbsp;类对WebRequest中定义的属性和方法提供支持，HttpWebRequest将发送到Internet资源的公共HTTP标头的值公开为属性，由方法或系统设置，常用的由属性或方法设置的HTTP标头为：接受,&nbsp;由Accept属性设置,&nbsp;连接,&nbsp;由Connection属性和KeepAlive属性设置,&nbsp;Content-Length,&nbsp;由ContentLength属性设置,&nbsp;Content-Type,&nbsp;由ContentType属性设置,&nbsp;范围,&nbsp;由AddRange方法设置.&nbsp;实际使用中是将标头信息正确设置后,传递到WEB服务器,WEB服务器根据要求作出回应。]]></description><content:encoded><![CDATA[很多人都有过使用网络蚂蚁或网络快车软件下载互联网文件的经历，这些软件的使用可以大大加速互联网上文件的传输速度，减少文件传输的时间。这些软件为什么有如此大的魔力呢？其主要原因是这些软件都采用了多线程下载和断点续传技术。如果我们自己来编写一个类似这样的程序，也能够快速的在互联网上下载文件，那一定是非常愉快的事情。下面我就讲一讲如何利用C#语言编写一个支持多线程下载文件的程序，你会看到利用C#语言编写网络应程序是多么的容易，从中也能体会到C#语言中强大的网络功能。<br><br>　　首先介绍一下HTTP协议，HTTP&nbsp;亦即Hpyer&nbsp;Text&nbsp;Transfer&nbsp;Protocal的缩写，它是现代互联网上最重要的一种网络协议，超文本传输协议位于TCP/IP协议的应用层，是一个面向无连接、简单、快速的C/S结构的协议。HTTP的工作过程大体上分连接、请求、响应和断开连接四个步骤。C#语言对HTTP协议提供了良好的支持，在.NET类库中提供了&nbsp;WebRequest和WebResponse类，这两个类都包含在System.Net命名空间中，利用这两个类可以实现很多高级的网络功能，本文中多线程文件下载就是利用这两个类实现的。&nbsp;WebRequest和WebResponse都是抽象基类，因此在程序中不能直接作为对象使用，必须被继承，实际使用中，可根据URI参数中的URI前缀选用它们合适的子类，对于HTTP这类URI,HttpWebRequest和HttpWebResponse类可以用于处理客户程序同WEB服务器之间的HTTP通讯。<br><br>　　HttpWebRequest类实现了很多通过HTTP访问WEB服务器上文件的高级功能。HttpWebRequest&nbsp;类对WebRequest中定义的属性和方法提供支持，HttpWebRequest将发送到Internet资源的公共HTTP标头的值公开为属性，由方法或系统设置，常用的由属性或方法设置的HTTP标头为：接受,&nbsp;由Accept属性设置,&nbsp;连接,&nbsp;由Connection属性和KeepAlive属性设置,&nbsp;Content-Length,&nbsp;由ContentLength属性设置,&nbsp;Content-Type,&nbsp;由ContentType属性设置,&nbsp;范围,&nbsp;由AddRange方法设置.&nbsp;实际使用中是将标头信息正确设置后,传递到WEB服务器,WEB服务器根据要求作出回应。<br><br>　　HttpWebResponse类继承自&nbsp;WebResponse类，专门处理从WEB服务器返回的HTTP响应，这个类实现了很多方法，具有很多属性，可以全面处理接收到的互联网信息。在&nbsp;HttpWebResponse类中，对于大多数通用的HTTP标头字段，都有独立的属性与其对应，程序员可以通过这些属性方便的访问位于HTTP接收报文标头字段中的信息，本例中用到的HttpWebResponse类属性为：ContentLength&nbsp;既接收内容的长度。<br><br>　　有了以上的了解后，下面看看这两个类的用法，要创建HttpWebRequest对象，不要直接使用HttpWebRequest的构造函数，而要使用WebRequest.Create方法初始化一个HttpWebRequest实例，如：<br><br>Code:&nbsp;<br>HttpWebRequest&nbsp;hwr=(HttpWebRequest)WebRequest.Create(<a target="_blank" href="http://www.163.com/);">http://www.163.com/);</a><br><br>创建了这个对象后，就可以通过HttpWebRequest属性，设置很多HTTP标头字段的内容,如hwr.AddRange(100,1000);设置接收对象的范围为100-1000字节。<br><br>　　HttpWebReques对象使用GetResponse()方法时，会返回一个HttpWebResponse对象，为提出HTTP返回报文信息，需要使用HttpWebResponse的GetResponseStream()方法，该方法返回一个Stream对象，可以读取HTTP返回的报文，如：首先定义一个Strean&nbsp;对象&nbsp;public&nbsp;System.IO.Stream&nbsp;ns;&nbsp;然后&nbsp;ns=hwr.GetResponse&nbsp;().GetResponseStream&nbsp;();即可创建Stream对象。有了以上的准备知识后下面开始设计我们的多线程互联网文件的下载程序，首先打开Visual&nbsp;Studio.Net集成开发环境，选择“文件”、“新建”、“项目”，然后选择“Visual&nbsp;C#项目”，在向导右边列表框中选中“Windows应用程序”，输入项目名称，如本例为：httpftp,然后选择“确定”按钮，向导自动生成了一个&nbsp;Windows应用程序项目。首先打开窗口设计器设计应用程序窗口，增加如下控件：<br><br>　　一个列表框&nbsp;listBox1&nbsp;三个文本标签&nbsp;label1-label3&nbsp;三个文本框&nbsp;textBox1-textBox3&nbsp;一个开始接收按钮&nbsp;button1&nbsp;设计好的窗口如下图：<br><br><br>打开Form1的代码编辑器，增加如下的命名空间：<br><br>Code:&nbsp;<br>using&nbsp;System.Net;//网络功能&nbsp;<br>using&nbsp;System.IO;//流支持<br>using&nbsp;System.Threading&nbsp;;//线程支持<br>　　<br><br>增加如下的程序变量：<br><br>Code:&nbsp;<br>public&nbsp;bool[]&nbsp;threadw;&nbsp;//每个线程结束标志<br>public&nbsp;string[]&nbsp;filenamew;//每个线程接收文件的文件名<br>public&nbsp;int[]&nbsp;filestartw;//每个线程接收文件的起始位置<br>public&nbsp;int[]&nbsp;filesizew;//每个线程接收文件的大小<br>public&nbsp;string&nbsp;strurl;//接受文件的URL<br>public&nbsp;bool&nbsp;hb;//文件合并标志<br>public&nbsp;int&nbsp;thread;//进程数<br>&nbsp;<br><br>定义一个HttpFile类，用于管理接收线程，其代码如下：<br><br>&nbsp;<br><br>public&nbsp;class&nbsp;HttpFile<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Form1&nbsp;formm;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;threadh;//线程代号<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;filename;//文件名<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;strUrl;//接收文件的URL<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;FileStream&nbsp;fs;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;HttpWebRequest&nbsp;request;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;System.IO.Stream&nbsp;ns;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;byte[]&nbsp;nbytes;//接收缓冲区<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;nreadsize;//接收字节数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;HttpFile(Form1&nbsp;form,int&nbsp;thread)//构造方法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formm=form;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threadh=thread;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~HttpFile()//析构方法<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formm.Dispose&nbsp;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;receive()//接收线程<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filename=formm.filenamew[threadh];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strUrl=formm.strurl;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ns=null;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nbytes=&nbsp;new&nbsp;byte[512];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nreadsize=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formm.listBox1&nbsp;.Items&nbsp;.Add&nbsp;(&quot;线程&quot;+threadh.ToString&nbsp;()+&quot;开始接收&quot;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs=new&nbsp;FileStream&nbsp;(filename,System.IO.FileMode.Create);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request=(HttpWebRequest)HttpWebRequest.Create&nbsp;(strUrl);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//接收的起始位置及接收的长度<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request.AddRange(formm.filestartw&nbsp;[threadh],<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formm.filestartw&nbsp;[threadh]+formm.filesizew&nbsp;[threadh]);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ns=request.GetResponse&nbsp;().GetResponseStream&nbsp;();//获得接收流<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nreadsize=ns.Read&nbsp;(nbytes,0,512);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(nreadsize&gt;0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs.Write&nbsp;(nbytes,0,nreadsize);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nreadsize=ns.Read&nbsp;(nbytes,0,512);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formm.listBox1&nbsp;.Items&nbsp;.Add&nbsp;(&quot;线程&quot;+threadh.ToString&nbsp;()+&quot;正在接收&quot;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs.Close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ns.Close&nbsp;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;er)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show&nbsp;(er.Message&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs.Close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formm.listBox1&nbsp;.Items.Add&nbsp;(&quot;进程&quot;+threadh.ToString&nbsp;()+&quot;接收完毕!&quot;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formm.threadw[threadh]=true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;该类和Form1类处于统一命名空间，但不包含在Form1类中。下面定义“开始接收”按钮控件的事件响应函数：<br><br>&nbsp;<br><br>private&nbsp;void&nbsp;button1_Click(object&nbsp;sender,&nbsp;System.EventArgs&nbsp;e)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;dt=DateTime.Now;//开始接收时间<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textBox1.Text&nbsp;=dt.ToString&nbsp;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strurl=textBox2.Text&nbsp;.Trim&nbsp;().ToString&nbsp;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpWebRequest&nbsp;request;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;long&nbsp;filesize=0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request=(HttpWebRequest)HttpWebRequest.Create&nbsp;(strurl);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filesize=request.GetResponse&nbsp;().ContentLength;//取得目标文件的长度<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request.Abort&nbsp;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;(Exception&nbsp;er)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show&nbsp;(er.Message&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;接收线程数<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thread=Convert.ToInt32&nbsp;(textBox4.Text&nbsp;.Trim().ToString&nbsp;(),10);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//根据线程数初始化数组<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threadw=new&nbsp;bool&nbsp;[thread];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filenamew=new&nbsp;string&nbsp;[thread];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filestartw=new&nbsp;int&nbsp;[thread];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filesizew=new&nbsp;int[thread];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//计算每个线程应该接收文件的大小<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;filethread=(int)filesize/thread;//平均分配<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;filethreade=filethread+(int)filesize%thread;//剩余部分由最后一个线程完成<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//为数组赋值<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i=0;ifalse;//每个线程状态的初始值为假<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filenamew[i]=i.ToString&nbsp;()+&quot;.dat&quot;;//每个线程接收文件的临时文件名<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i//每个线程接收文件的起始点<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filesizew[i]=filethread-1;//每个线程接收文件的长度<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filestartw[i]=filethread*i;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filesizew[i]=filethreade-1;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//定义线程数组，启动接收线程<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread[]&nbsp;threadk=new&nbsp;Thread&nbsp;[thread];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpFile[]&nbsp;httpfile=new&nbsp;HttpFile&nbsp;[thread];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;j=0;jnew&nbsp;HttpFile(this,j);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threadk[j]=new&nbsp;Thread(new&nbsp;ThreadStart&nbsp;(httpfile[j].receive&nbsp;));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threadk[j].Start&nbsp;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//启动合并各线程接收的文件线程<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread&nbsp;hbth=new&nbsp;Thread&nbsp;(new&nbsp;ThreadStart&nbsp;(hbfile));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hbth.Start&nbsp;();<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;合并文件的线程hbfile定义在Form1类中,定义如下：<br><br>public&nbsp;void&nbsp;hbfile()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(true)//等待<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hb=true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;i=0;iif&nbsp;(threadw[i]==false)//有未结束线程，等待<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hb=false;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep&nbsp;(100);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(hb==true)//所有线程均已结束，停止等待，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileStream&nbsp;fs;//开始合并<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileStream&nbsp;fstemp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;readfile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[]&nbsp;bytes=new&nbsp;byte[512];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs=new&nbsp;FileStream&nbsp;(textBox3.Text&nbsp;.Trim&nbsp;().ToString&nbsp;(),System.IO.FileMode.Create);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(int&nbsp;k=0;knew&nbsp;FileStream&nbsp;(filenamew[k],System.IO.FileMode&nbsp;.Open);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(true)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;readfile=fstemp.Read&nbsp;(bytes,0,512);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(readfile&gt;0)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs.Write&nbsp;(bytes,0,readfile);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fstemp.Close&nbsp;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fs.Close&nbsp;();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateTime&nbsp;dt=DateTime.Now;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;textBox1.Text&nbsp;=dt.ToString&nbsp;();//结束时间<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show&nbsp;(&quot;接收完毕!!!&quot;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<br><br>&nbsp;至此，一个多线程下载文件的程序就大功告成了，注意在输入本地文件名时，应按如下格式输入：<br><br>“c:\\test\\httpftp\\bin\\d.htm”，因”\”后的字符在C#中是转义字符，线程数并非越大越好，一般5个线程就可以了，该程序在Visual&nbsp;Studio.Net&nbsp;2002开发环境及Windows&nbsp;xp&nbsp;操作系统上通过。<br><br>]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=35</link><dc:subject>asp.net</dc:subject><dc:creator>admin</dc:creator><dc:date>2007-12-7 17:09:24</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=34"><title><![CDATA[使用 SQL Server 时需要经常用到的几个设置选项！]]></title><description><![CDATA[1.&nbsp;SET&nbsp;DEADLOCK_PRIORITY<br><br>说明：控制在发生死锁情况时会话的反应方式。如果两个进程都锁定数据，并且直到其它进程释放自己的锁时，每个进程才能释放自己的锁，即发生死锁情况。<br><br>语法：SET&nbsp;DEADLOCK_PRIORITY&nbsp;{&nbsp;LOW&nbsp;|&nbsp;NORMAL&nbsp;|&nbsp;@deadlock_var&nbsp;}]]></description><content:encoded><![CDATA[1.&nbsp;SET&nbsp;DEADLOCK_PRIORITY<br><br>说明：控制在发生死锁情况时会话的反应方式。如果两个进程都锁定数据，并且直到其它进程释放自己的锁时，每个进程才能释放自己的锁，即发生死锁情况。<br><br>语法：SET&nbsp;DEADLOCK_PRIORITY&nbsp;{&nbsp;LOW&nbsp;|&nbsp;NORMAL&nbsp;|&nbsp;@deadlock_var&nbsp;}<br><br>参数：LOW&nbsp;&nbsp;指定当前会话为首选死锁牺牲品。Microsoft®&nbsp;SQL&nbsp;Server™&nbsp;自动回滚死锁牺牲品的事务，并给客户端应用程序返回&nbsp;1205&nbsp;号死锁错误信息。<br>　　　NORMAL&nbsp;&nbsp;指定会话返回到默认的死锁处理方法。<br>　　　@deadlock_var&nbsp;是指定死锁处理方法的字符变量。如果指定&nbsp;LOW，则&nbsp;@deadlock_var&nbsp;为&nbsp;3；如果指定&nbsp;NORMAL，则&nbsp;@deadlock_var&nbsp;为&nbsp;6。<br><br>注释：SET&nbsp;DEADLOCK_PRIORITY&nbsp;的设置是在执行或运行时设置，而不是在分析时设置。<br><br>权限：SET&nbsp;DEADLOCK_PRIORITY&nbsp;权限默认授予所有用户。<br><br>&nbsp;<br><br>2.&nbsp;SET&nbsp;LOCK_TIMEOUT<br><br>说明：指定语句等待锁释放的毫秒数。<br><br>语法：SET&nbsp;LOCK_TIMEOUT&nbsp;timeout_period<br><br>参数：timeout_period&nbsp;是在&nbsp;Microsoft®&nbsp;SQL&nbsp;Server™&nbsp;返回锁定错误前经过的毫秒数。值为&nbsp;-1（默认值）时表示没有超时期限（即无限期等待）。<br>　　　&nbsp;&nbsp;&nbsp;当锁等待超过超时值时，将返回错误。值为&nbsp;0&nbsp;时表示根本不等待，并且一遇到锁就返回信息。<br><br>注释：在连接开始时，该设置的值为&nbsp;-1。设置更改后，新设置在其余的连接时间里一直有效。<br>　　　SET&nbsp;LOCK_TIMEOUT&nbsp;的设置是在执行或运行时设置，而不是在分析时设置。<br>　　　READPAST&nbsp;锁定提示为该&nbsp;SET&nbsp;选项提供了另一种方式。<br><br>权限：SET&nbsp;LOCK_TIMEOUT&nbsp;权限默认授予所有用户。<br><br>示例：下例将锁超时期限设置为&nbsp;1,800&nbsp;毫秒。<br><br>　　　SET&nbsp;LOCK_TIMEOUT&nbsp;1800<br>　　　GO<br><br>&nbsp;<br><br>3.&nbsp;@@LOCK_TIMEOUT<br><br>说明：返回当前会话的当前锁超时设置，单位为毫秒。<br><br>语法：@@LOCK_TIMEOUT<br><br>返回类型：integer<br><br>注释：SET&nbsp;LOCK_TIMEOUT&nbsp;允许应用程序设置语句等待阻塞资源的最长时间。当一条语句已等待超过&nbsp;LOCK_TIMEOUT&nbsp;所设置的时间，则被锁住的语句将自动取消，并给应用程序返回一条错误信息。<br>　　　在一个连接的开始，@@LOCK_TIMEOUT&nbsp;返回一个&nbsp;–1值。<br><br>示例：下面的示例显示当一个&nbsp;LOCK_TIMEOUT&nbsp;值未被设置时的结果集。<br><br>　　　SELECT&nbsp;@@LOCK_TIMEOUT<br>　　　下面是结果集：<br>　　　----------------<br>　　　-1<br><br>　　　下面的示例设置&nbsp;LOCK_TIMEOUT&nbsp;为&nbsp;1800&nbsp;毫秒，然后调用&nbsp;@@LOCK_TIMEOUT。<br><br>　　　SET&nbsp;LOCK_TIMEOUT&nbsp;1800<br>　　　SELECT&nbsp;@@LOCK_TIMEOUT<br><br>　　　下面是结果集：<br>　　　------------------------------<br>　　　1800<br><br>&nbsp;<br><br>4.&nbsp;SET&nbsp;IDENTITY_INSERT<br><br>说明：允许将显式值插入表的标识列中。<br><br>语法：SET&nbsp;IDENTITY_INSERT&nbsp;[&nbsp;database.[&nbsp;owner.]&nbsp;]&nbsp;{&nbsp;table&nbsp;}&nbsp;{&nbsp;ON&nbsp;|&nbsp;OFF&nbsp;}<br><br>参数：database&nbsp;是指定的表所驻留的数据库名称。<br>　　　owner&nbsp;是表所有者的名称。<br>　　　table&nbsp;是含有标识列的表名。<br><br>注释：任何时候，会话中只有一个表的&nbsp;IDENTITY_INSERT&nbsp;属性可以设置为&nbsp;ON。如果某个表已将此属性设置为&nbsp;ON，并且为另一个表发出了&nbsp;SET&nbsp;IDENTITY_INSERT&nbsp;ON&nbsp;语句，则&nbsp;Microsoft®&nbsp;SQL&nbsp;Server™&nbsp;返回一个错误信息，指出&nbsp;SET&nbsp;IDENTITY_INSERT&nbsp;已设置为&nbsp;ON&nbsp;并报告此属性已设置为&nbsp;ON&nbsp;的表。<br>　　　如果插入值大于表的当前标识值，则&nbsp;SQL&nbsp;Server&nbsp;自动将新插入值作为当前标识值使用。<br>　　　SET&nbsp;IDENTITY_INSERT&nbsp;的设置是在执行或运行时设置，而不是在分析时设置。<br><br>权限：执行权限默认授予&nbsp;sysadmin&nbsp;固定服务器角色和&nbsp;db_owner&nbsp;及&nbsp;db_ddladmin&nbsp;固定数据库角色以及对象所有者。<br><br>示例：下例创建一个含有标识列的表，并显示如何使用&nbsp;SET&nbsp;IDENTITY_INSERT&nbsp;设置填充由&nbsp;DELETE&nbsp;语句导致的标识值中的空隙。<br><br>　　　--&nbsp;Create&nbsp;products&nbsp;table.<br>　　　CREATE&nbsp;TABLE&nbsp;products&nbsp;(id&nbsp;int&nbsp;IDENTITY&nbsp;PRIMARY&nbsp;KEY,&nbsp;product&nbsp;varchar(40))<br>　　　GO<br>　　　--&nbsp;Inserting&nbsp;values&nbsp;into&nbsp;products&nbsp;table.<br>　　　INSERT&nbsp;INTO&nbsp;products&nbsp;(product)&nbsp;VALUES&nbsp;(&#39;screwdriver&#39;)<br>　　　INSERT&nbsp;INTO&nbsp;products&nbsp;(product)&nbsp;VALUES&nbsp;(&#39;hammer&#39;)<br>　　　INSERT&nbsp;INTO&nbsp;products&nbsp;(product)&nbsp;VALUES&nbsp;(&#39;saw&#39;)<br>　　　INSERT&nbsp;INTO&nbsp;products&nbsp;(product)&nbsp;VALUES&nbsp;(&#39;shovel&#39;)<br>　　　GO<br><br>　　　--&nbsp;Create&nbsp;a&nbsp;gap&nbsp;in&nbsp;the&nbsp;identity&nbsp;values.<br>　　　DELETE&nbsp;products&nbsp;<br>　　　WHERE&nbsp;product&nbsp;=&nbsp;&#39;saw&#39;<br>　　　GO<br><br>　　　SELECT&nbsp;*&nbsp;<br>　　　FROM&nbsp;products<br>　　　GO<br><br>　　　--&nbsp;Attempt&nbsp;to&nbsp;insert&nbsp;an&nbsp;explicit&nbsp;ID&nbsp;value&nbsp;of&nbsp;3;<br>　　　--&nbsp;should&nbsp;return&nbsp;a&nbsp;warning.<br>　　　INSERT&nbsp;INTO&nbsp;products&nbsp;(id,&nbsp;product)&nbsp;VALUES(3,&nbsp;&#39;garden&nbsp;shovel&#39;)<br>　　　GO<br><br>　　　--&nbsp;SET&nbsp;IDENTITY_INSERT&nbsp;to&nbsp;ON.<br>　　　SET&nbsp;IDENTITY_INSERT&nbsp;products&nbsp;ON<br>　　　GO<br><br>　　　--&nbsp;Attempt&nbsp;to&nbsp;insert&nbsp;an&nbsp;explicit&nbsp;ID&nbsp;value&nbsp;of&nbsp;3<br>　　　INSERT&nbsp;INTO&nbsp;products&nbsp;(id,&nbsp;product)&nbsp;VALUES(3,&nbsp;&#39;garden&nbsp;shovel&#39;)<br>　　　GO<br><br>　　　SELECT&nbsp;*&nbsp;<br>　　　FROM&nbsp;products<br>　　　GO<br><br>　　　--&nbsp;Drop&nbsp;products&nbsp;table.<br>　　　DROP&nbsp;TABLE&nbsp;products<br>　　　GO<br><br>&nbsp;<br><br>5.&nbsp;SET&nbsp;IMPLICIT_TRANSACTIONS<br><br>说明：为连接设置隐性事务模式。<br><br>语法：SET&nbsp;IMPLICIT_TRANSACTIONS&nbsp;{&nbsp;ON&nbsp;|&nbsp;OFF&nbsp;}<br><br>注释：当设置为&nbsp;ON&nbsp;时，SET&nbsp;IMPLICIT_TRANSACTIONS&nbsp;将连接设置为隐性事务模式。当设置为&nbsp;OFF&nbsp;时，则使连接返回到自动提交事务模式。<br>　　　当连接是隐性事务模式且当前不在事务中时，执行下列语句将启动事务：<br><br>　　　ALTER&nbsp;TABLE&nbsp;FETCH&nbsp;REVOKE&nbsp;<br>　　　CREATE&nbsp;&nbsp;GRANT&nbsp;SELECT&nbsp;<br>　　　DELETE&nbsp;INSERT&nbsp;TRUNCATE&nbsp;TABLE&nbsp;<br>　　　DROP&nbsp;OPEN&nbsp;UPDATE&nbsp;<br><br>　　　如果连接已经在打开的事务中，则上述语句不启动新事务。<br>　　　对于因为该设置为&nbsp;ON&nbsp;而自动打开的事务，用户必须在该事务结束时将其显式提交或回滚。否则当用户断开连接时，事务及其所包含的所有数据更改将回滚。在事务提交后，执行上述任一语句即可启动新事务。<br>　　　隐性事务模式将保持有效，直到连接执行&nbsp;SET&nbsp;IMPLICIT_TRANSACTIONS&nbsp;OFF&nbsp;语句使连接返回到自动提交模式。在自动提交模式下，如果各个语句成功完成则提交。<br>　　　在进行连接时，SQL&nbsp;Server&nbsp;ODBC&nbsp;驱动程序和用于&nbsp;SQL&nbsp;Server&nbsp;的&nbsp;Microsoft&nbsp;OLE&nbsp;DB&nbsp;提供程序自动将&nbsp;IMPLICIT_TRANSACTIONS&nbsp;设置为&nbsp;OFF。对来自&nbsp;DB-Library&nbsp;应用程序的连接，SET&nbsp;IMPLICIT_TRANSACTIONS&nbsp;默认为&nbsp;OFF。<br>　　　当&nbsp;SET&nbsp;ANSI_DEFAULTS&nbsp;为&nbsp;ON&nbsp;时，将启用&nbsp;SET&nbsp;IMPLICIT_TRANSACTIONS。<br>　　　SET&nbsp;IMPLICIT_TRANSACTIONS&nbsp;的设置是在执行或运行时设置，而不是在分析时设置。<br><br>示例：下例演示在将&nbsp;IMPLICIT_TRANSACTIONS&nbsp;设置为&nbsp;ON&nbsp;时显式或隐式启动事务。它使用&nbsp;@@TRANCOUNT&nbsp;函数演示打开的事务和关闭的事务。<br><br>　　　USE&nbsp;pubs<br>　　　GO<br><br>　　　CREATE&nbsp;table&nbsp;t1&nbsp;(a&nbsp;int)<br>　　　GO<br>　　　INSERT&nbsp;INTO&nbsp;t1&nbsp;VALUES&nbsp;(1)<br>　　　GO<br><br>　　　PRINT&nbsp;&#39;Use&nbsp;explicit&nbsp;transaction&#39;<br>　　　BEGIN&nbsp;TRAN<br>　　　INSERT&nbsp;INTO&nbsp;t1&nbsp;VALUES&nbsp;(2)<br>　　　SELECT&nbsp;&#39;Tran&nbsp;count&nbsp;in&nbsp;transaction&#39;=&nbsp;@@TRANCOUNT<br>　　　COMMIT&nbsp;TRAN<br>　　　SELECT&nbsp;&#39;Tran&nbsp;count&nbsp;outside&nbsp;transaction&#39;=&nbsp;@@TRANCOUNT<br>　　　GO<br><br>　　　PRINT&nbsp;&#39;Setting&nbsp;IMPLICIT_TRANSACTIONS&nbsp;ON&#39;<br>　　　GO<br>　　　SET&nbsp;IMPLICIT_TRANSACTIONS&nbsp;ON<br>　　　GO<br><br>　　　PRINT&nbsp;&#39;Use&nbsp;implicit&nbsp;transactions&#39;<br>　　　GO<br>　　　--&nbsp;No&nbsp;BEGIN&nbsp;TRAN&nbsp;needed&nbsp;here.<br>　　　INSERT&nbsp;INTO&nbsp;t1&nbsp;VALUES&nbsp;(4)<br>　　　SELECT&nbsp;&#39;Tran&nbsp;count&nbsp;in&nbsp;transaction&#39;=&nbsp;@@TRANCOUNT<br>　　　COMMIT&nbsp;TRAN<br>　　　SELECT&nbsp;&#39;Tran&nbsp;count&nbsp;outside&nbsp;transaction&#39;=&nbsp;@@TRANCOUNT<br>　　　GO<br><br>　　　PRINT&nbsp;&#39;Use&nbsp;explicit&nbsp;transactions&nbsp;with&nbsp;IMPLICIT_TRANSACTIONS&nbsp;ON&#39;<br>　　　GO<br>　　　BEGIN&nbsp;TRAN<br>　　　INSERT&nbsp;INTO&nbsp;t1&nbsp;VALUES&nbsp;(5)<br>　　　SELECT&nbsp;&#39;Tran&nbsp;count&nbsp;in&nbsp;transaction&#39;=&nbsp;@@TRANCOUNT<br>　　　COMMIT&nbsp;TRAN<br>　　　SELECT&nbsp;&#39;Tran&nbsp;count&nbsp;outside&nbsp;transaction&#39;=&nbsp;@@TRANCOUNT<br>　　　GO<br><br>　　　SELECT&nbsp;*&nbsp;FROM&nbsp;t1<br>　　　GO<br><br>　　　--&nbsp;Need&nbsp;to&nbsp;commit&nbsp;this&nbsp;tran&nbsp;too!<br>　　　DROP&nbsp;TABLE&nbsp;t1<br>　　　COMMIT&nbsp;TRAN<br>　　　GO<br><br>&nbsp;<br><br>6.&nbsp;SET&nbsp;NOCOUNT<br>说明：使返回的结果中不包含有关受&nbsp;Transact-SQL&nbsp;语句影响的行数的信息。<br><br>语法：SET&nbsp;NOCOUNT&nbsp;{&nbsp;ON&nbsp;|&nbsp;OFF&nbsp;}&nbsp;<br><br>注释：当&nbsp;SET&nbsp;NOCOUNT&nbsp;为&nbsp;ON&nbsp;时，不返回计数（表示受&nbsp;Transact-SQL&nbsp;语句影响的行数）。当&nbsp;SET&nbsp;NOCOUNT&nbsp;为&nbsp;OFF&nbsp;时，返回计数。<br>　　　即使当&nbsp;SET&nbsp;NOCOUNT&nbsp;为&nbsp;ON&nbsp;时，也更新&nbsp;@@ROWCOUNT&nbsp;函数。<br>　　　当&nbsp;SET&nbsp;NOCOUNT&nbsp;为&nbsp;ON&nbsp;时，将不给客户端发送存储过程中的每个语句的&nbsp;DONE_IN_PROC&nbsp;信息。当使用&nbsp;Microsoft®&nbsp;SQL&nbsp;Server™&nbsp;提供的实用工具执行查询时，在&nbsp;Transact-SQL&nbsp;语句（如&nbsp;SELECT、INSERT、UPDATE&nbsp;和&nbsp;DELETE）结束时将不会在查询结果中显示&quot;nn&nbsp;rows&nbsp;affected&quot;。<br>　　　如果存储过程中包含的一些语句并不返回许多实际的数据，则该设置由于大量减少了网络流量，因此可显著提高性能。<br>　　　SET&nbsp;NOCOUNT&nbsp;设置是在执行或运行时设置，而不是在分析时设置。<br><br>权限：SET&nbsp;NOCOUNT&nbsp;权限默认授予所有用户。<br><br>示例：下例在&nbsp;osql&nbsp;实用工具或&nbsp;SQL&nbsp;Server&nbsp;查询分析器中执行时，可防止显示有关受影响的行数的信息。<br><br>　　　USE&nbsp;pubs<br>　　　GO<br>　　　--&nbsp;Display&nbsp;the&nbsp;count&nbsp;message.<br>　　　SELECT&nbsp;au_lname&nbsp;<br>　　　FROM&nbsp;authors<br>　　　GO<br>　　　USE&nbsp;pubs<br>　　　GO<br>　　　--&nbsp;SET&nbsp;NOCOUNT&nbsp;to&nbsp;ON&nbsp;and&nbsp;no&nbsp;longer&nbsp;display&nbsp;the&nbsp;count&nbsp;message.<br>　　　SET&nbsp;NOCOUNT&nbsp;ON<br>　　　GO<br>　　　SELECT&nbsp;au_lname&nbsp;<br>　　　FROM&nbsp;authors<br>　　　GO<br>　　　--&nbsp;Reset&nbsp;SET&nbsp;NOCOUNT&nbsp;to&nbsp;OFF.<br>　　　SET&nbsp;NOCOUNT&nbsp;OFF<br>　　　GO<br><br>&nbsp;<br><br>7.&nbsp;@@ROWCOUNT<br>说明：返回受上一语句影响的行数。<br><br>语法：@@ROWCOUNT<br><br>返回类型：integer<br><br>注释：任何不返回行的语句将这一变量设置为&nbsp;0&nbsp;，如&nbsp;IF&nbsp;语句。<br><br>示例：下面的示例执行&nbsp;UPDATE&nbsp;语句并用&nbsp;@@ROWCOUNT&nbsp;来检测是否有发生更改的行。<br><br>　　　UPDATE&nbsp;authors&nbsp;SET&nbsp;au_lname&nbsp;=&nbsp;&#39;Jones&#39;<br>　　　WHERE&nbsp;au_id&nbsp;=&nbsp;&#39;999-888-7777&#39;<br>　　　IF&nbsp;@@ROWCOUNT&nbsp;=&nbsp;0<br>　　　&nbsp;&nbsp;&nbsp;print&nbsp;&#39;Warning:&nbsp;No&nbsp;rows&nbsp;were&nbsp;updated&#39;<br><br>&nbsp;<br><br>8.&nbsp;SET&nbsp;ROWCOUNT<br><br>说明：使&nbsp;Microsoft®&nbsp;SQL&nbsp;Server™&nbsp;在返回指定的行数之后停止处理查询。&nbsp;<br><br>语法：SET&nbsp;ROWCOUNT&nbsp;{&nbsp;number&nbsp;|&nbsp;@number_var&nbsp;}&nbsp;<br><br>参数：number&nbsp;|&nbsp;@number_var&nbsp;是在停止给定查询之前要处理的行数（整数）。<br><br>注释：建议将当前使用&nbsp;SET&nbsp;ROWCOUNT&nbsp;的&nbsp;DELETE、INSERT&nbsp;和&nbsp;UPDATE&nbsp;语句重新编写为使用&nbsp;TOP&nbsp;语法。有关更多信息，请参见&nbsp;DELETE、INSERT&nbsp;或&nbsp;UPDATE。<br>　　　对于在远程表和本地及远程分区视图上执行的&nbsp;INSERT、UPDATE&nbsp;和&nbsp;DELETE&nbsp;语句，忽略&nbsp;SET&nbsp;ROWCOUNT&nbsp;选项设置。<br>　　　若要关闭该选项（以便返回所有的行），请将&nbsp;SET&nbsp;ROWCOUNT&nbsp;指定为&nbsp;0。<br>　　　说明&nbsp;&nbsp;设置&nbsp;SET&nbsp;ROWCOUNT&nbsp;选项将使大多数&nbsp;Transact-SQL&nbsp;语句在已受指定数目的行影响后停止处理。这包括触发器和&nbsp;INSERT、UPDATE&nbsp;及&nbsp;DELETE&nbsp;等数据修改语句。ROWCOUNT&nbsp;选项对动态游标无效，但限制键集的行集和不感知游标。使用该选项时应谨慎，它主要与&nbsp;SELECT&nbsp;语句一起使用。<br>　　　如果行数的值较小，则&nbsp;SET&nbsp;ROWCOUNT&nbsp;替代&nbsp;SELECT&nbsp;语句&nbsp;TOP&nbsp;关键字。<br>　　　SET&nbsp;ROWCOUNT&nbsp;的设置是在执行或运行时设置，而不是在分析时设置。<br><br>权限：SET&nbsp;ROWCOUNT&nbsp;权限默认授予所有用户。<br><br>示例：SET&nbsp;ROWCOUNT&nbsp;在指定的行数后停止处理。在下例中，注意有&nbsp;x&nbsp;行满足预付款少于或等于&nbsp;$5,000&nbsp;的条件；但是，从更新所返回的行数中可以看出并非所有的行都得到处理。ROWCOUNT&nbsp;影响所有的&nbsp;Transact-SQL&nbsp;语句。<br><br>　　　USE&nbsp;pubs<br>　　　GO<br>　　　SELECT&nbsp;count(*)&nbsp;AS&nbsp;Cnt<br>　　　FROM&nbsp;titles&nbsp;<br>　　　WHERE&nbsp;advance&nbsp;&gt;=&nbsp;5000<br>　　　GO<br><br>　　　下面是结果集：<br><br>　　　Cnt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>　　　-----------&nbsp;<br>　　　11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>　　　(1&nbsp;row(s)&nbsp;affected)<br><br>　　　现在，将&nbsp;ROWCOUNT&nbsp;设置为&nbsp;4，并更新预付款等于或大于&nbsp;$5,000&nbsp;的所有行。<br><br>　　　--&nbsp;SET&nbsp;ROWCOUNT&nbsp;to&nbsp;4.<br>　　　SET&nbsp;ROWCOUNT&nbsp;4<br>　　　GO<br>　　　UPDATE&nbsp;titles<br>　　　SET&nbsp;advance&nbsp;=&nbsp;5000<br>　　　WHERE&nbsp;advance&nbsp;&gt;=&nbsp;5000<br>　　　GO<br><br>&nbsp;<br><br>9.&nbsp;SET&nbsp;TRANSACTION&nbsp;ISOLATION&nbsp;LEVEL<br>说明：控制由连接发出的所有&nbsp;Microsoft®&nbsp;SQL&nbsp;Server™&nbsp;SELECT&nbsp;语句的默认事务锁定行为。<br><br>语法：SET&nbsp;TRANSACTION&nbsp;ISOLATION&nbsp;LEVEL<br>　　　{&nbsp;READ&nbsp;COMMITTED<br>　　　&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;READ&nbsp;UNCOMMITTED<br>　　　&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;REPEATABLE&nbsp;READ<br>　　　&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;SERIALIZABLE&nbsp;<br>　　　}<br><br>参数：READ&nbsp;COMMITTED&nbsp;指定在读取数据时控制共享锁以避免脏读，但数据可在事务结束前更改，从而产生不可重复读取或幻像数据。该选项是&nbsp;SQL&nbsp;Server&nbsp;的默认值。<br>　　　READ&nbsp;UNCOMMITTED&nbsp;执行脏读或&nbsp;0&nbsp;级隔离锁定，这表示不发出共享锁，也不接受排它锁。当设置该选项时，可以对数据执行未提交读或脏读；在事务结束前可以更改数据内的数值，行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置&nbsp;NOLOCK&nbsp;相同。这是四个隔离级别中限制最小的级别。<br>　　　REPEATABLE&nbsp;READ&nbsp;锁定查询中使用的所有数据以防止其他用户更新数据，但是其他用户可以将新的幻像行插入数据集，且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别，所以应只在必要时才使用该选项。<br>　　　SERIALIZABLE&nbsp;在数据集上放置一个范围锁，以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低，所以应只在必要时才使用该选项。该选项的作用与在事务内所有&nbsp;SELECT&nbsp;语句中的所有表上设置&nbsp;HOLDLOCK&nbsp;相同。<br><br>注释：一次只能设置这些选项中的一个，而且设置的选项将一直对那个连接保持有效，直到显式更改该选项为止。这是默认行为，除非在语句的&nbsp;FROM&nbsp;子句中在表级上指定优化选项。<br>　　　SET&nbsp;TRANSACTION&nbsp;ISOLATION&nbsp;LEVEL&nbsp;的设置是在执行或运行时设置，而不是在分析时设置。<br><br>示例：下例为会话设置&nbsp;TRANSACTION&nbsp;ISOLATION&nbsp;LEVEL。对于每个后续&nbsp;Transact-SQL&nbsp;语句，SQL&nbsp;Server&nbsp;将所有共享锁一直控制到事务结束为止。<br><br>　　　SET&nbsp;TRANSACTION&nbsp;ISOLATION&nbsp;LEVEL&nbsp;REPEATABLE&nbsp;READ<br>　　　GO<br>　　　BEGIN&nbsp;TRANSACTION<br>　　　SELECT&nbsp;*&nbsp;FROM&nbsp;publishers<br>　　　SELECT&nbsp;*&nbsp;FROM&nbsp;authors<br>　　　...<br>　　　COMMIT&nbsp;TRANSACTION<br><br>&nbsp;<br><br>10.&nbsp;SET&nbsp;XACT_ABORT<br><br>说明：指定当&nbsp;Transact-SQL&nbsp;语句产生运行时错误时，Microsoft®&nbsp;SQL&nbsp;Server™&nbsp;是否自动回滚当前事务。<br><br>语法：SET&nbsp;XACT_ABORT&nbsp;{&nbsp;ON&nbsp;|&nbsp;OFF&nbsp;}<br><br>注释：当&nbsp;SET&nbsp;XACT_ABORT&nbsp;为&nbsp;ON&nbsp;时，如果&nbsp;Transact-SQL&nbsp;语句产生运行时错误，整个事务将终止并回滚。为&nbsp;OFF&nbsp;时，只回滚产生错误的&nbsp;Transact-SQL&nbsp;语句，而事务将继续进行处理。编译错误（如语法错误）不受&nbsp;SET&nbsp;XACT_ABORT&nbsp;的影响。<br>　　　对于大多数&nbsp;OLE&nbsp;DB&nbsp;提供程序（包括&nbsp;SQL&nbsp;Server），隐性或显式事务中的数据修改语句必须将&nbsp;XACT_ABORT&nbsp;设置为&nbsp;ON。唯一不需要该选项的情况是提供程序支持嵌套事务时。有关更多信息，请参见分布式查询和分布式事务。&nbsp;<br>　　　SET&nbsp;XACT_ABORT&nbsp;的设置是在执行或运行时设置，而不是在分析时设置。<br><br>示例：下例导致在含有其它&nbsp;Transact-SQL&nbsp;语句的事务中发生违反外键错误。在第一个语句集中产生错误，但其它语句均成功执行且事务成功提交。在第二个语句集中，SET&nbsp;XACT_ABORT&nbsp;设置为&nbsp;ON。这导致语句错误使批处理终止，并使事务回滚。&nbsp;<br><br>　　　CREATE&nbsp;TABLE&nbsp;t1&nbsp;(a&nbsp;int&nbsp;PRIMARY&nbsp;KEY)<br>　　　CREATE&nbsp;TABLE&nbsp;t2&nbsp;(a&nbsp;int&nbsp;REFERENCES&nbsp;t1(a))<br>　　　GO<br>　　　INSERT&nbsp;INTO&nbsp;t1&nbsp;VALUES&nbsp;(1)<br>　　　INSERT&nbsp;INTO&nbsp;t1&nbsp;VALUES&nbsp;(3)<br>　　　INSERT&nbsp;INTO&nbsp;t1&nbsp;VALUES&nbsp;(4)<br>　　　INSERT&nbsp;INTO&nbsp;t1&nbsp;VALUES&nbsp;(6)<br>　　　GO<br>　　　SET&nbsp;XACT_ABORT&nbsp;OFF<br>　　　GO<br>　　　BEGIN&nbsp;TRAN<br>　　　INSERT&nbsp;INTO&nbsp;t2&nbsp;VALUES&nbsp;(1)<br>　　　INSERT&nbsp;INTO&nbsp;t2&nbsp;VALUES&nbsp;(2)&nbsp;/*&nbsp;Foreign&nbsp;key&nbsp;error&nbsp;*/<br>　　　INSERT&nbsp;INTO&nbsp;t2&nbsp;VALUES&nbsp;(3)<br>　　　COMMIT&nbsp;TRAN<br>　　　GO<br><br>　　　SET&nbsp;XACT_ABORT&nbsp;ON<br>　　　GO<br><br>　　　BEGIN&nbsp;TRAN<br>　　　INSERT&nbsp;INTO&nbsp;t2&nbsp;VALUES&nbsp;(4)<br>　　　INSERT&nbsp;INTO&nbsp;t2&nbsp;VALUES&nbsp;(5)&nbsp;/*&nbsp;Foreign&nbsp;key&nbsp;error&nbsp;*/<br>　　　INSERT&nbsp;INTO&nbsp;t2&nbsp;VALUES&nbsp;(6)<br>　　　COMMIT&nbsp;TRAN<br>　　　GO<br><br>　　　/*&nbsp;Select&nbsp;shows&nbsp;only&nbsp;keys&nbsp;1&nbsp;and&nbsp;3&nbsp;added.&nbsp;<br>　　　&nbsp;&nbsp;&nbsp;Key&nbsp;2&nbsp;insert&nbsp;failed&nbsp;and&nbsp;was&nbsp;rolled&nbsp;back,&nbsp;but<br>　　　&nbsp;&nbsp;&nbsp;XACT_ABORT&nbsp;was&nbsp;OFF&nbsp;and&nbsp;rest&nbsp;of&nbsp;transaction<br>　　　&nbsp;&nbsp;&nbsp;succeeded.<br>　　　&nbsp;&nbsp;&nbsp;Key&nbsp;5&nbsp;insert&nbsp;error&nbsp;with&nbsp;XACT_ABORT&nbsp;ON&nbsp;caused<br>　　　&nbsp;&nbsp;&nbsp;all&nbsp;of&nbsp;the&nbsp;second&nbsp;transaction&nbsp;to&nbsp;roll&nbsp;back.&nbsp;*/<br><br>　　　SELECT&nbsp;*&nbsp;<br>　　　FROM&nbsp;t2<br>　　　GO<br><br>　　　DROP&nbsp;TABLE&nbsp;t2<br>　　　DROP&nbsp;TABLE&nbsp;t1<br>　　　GO<br><br>]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=34</link><dc:subject>sqlserver</dc:subject><dc:creator>admin</dc:creator><dc:date>2007-9-30 16:54:36</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=33"><title><![CDATA[生成随机数]]></title><description><![CDATA[select&nbsp;RIGHT(100000000&nbsp;+&nbsp;CONVERT(bigint,&nbsp;ABS(CHECKSUM(NEWID()))),&nbsp;8)<br>]]></description><content:encoded><![CDATA[select&nbsp;RIGHT(100000000&nbsp;+&nbsp;CONVERT(bigint,&nbsp;ABS(CHECKSUM(NEWID()))),&nbsp;8)<br>]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=33</link><dc:subject>sqlserver</dc:subject><dc:creator>admin</dc:creator><dc:date>2007-9-7 11:45:53</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=31"><title><![CDATA[IIS]]></title><description><![CDATA[https://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/386f34b9-37c8-4c78-8bc1-45c3859fc163.mspx?mfr=true]]></description><content:encoded><![CDATA[<a target="_blank" href="https://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/386f34b9-37c8-4c78-8bc1-45c3859fc163.mspx?mfr=true">https://www.microsoft.com/technet/prodtechnol/WindowsServer2003 ... 8-4c78-8bc1-45c3859fc163.mspx?mfr=true</a>]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=31</link><dc:subject>asp</dc:subject><dc:creator>admin</dc:creator><dc:date>2007-7-4 15:17:15</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=30"><title><![CDATA[php IIS设置]]></title><description><![CDATA[php5ts.dll&nbsp;-&gt;c:\windows\system32<br>php.ini&nbsp;-&gt;&nbsp;c:\windows<br><br>单独建立应用程序池]]></description><content:encoded><![CDATA[php5ts.dll&nbsp;-&gt;c:\windows\system32<br>php.ini&nbsp;-&gt;&nbsp;c:\windows<br><br>单独建立应用程序池]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=30</link><dc:subject>php</dc:subject><dc:creator>admin</dc:creator><dc:date>2007-3-22 19:33:47</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=29"><title><![CDATA[sel&#101;ct时锁定记录问题]]></title><description><![CDATA[在使用SQL时，大都会遇到这样的问题，你Update一条记录时，需要通过Select来检索出其值或条件，然后在通过这个值来执行修改操作。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;但当以上操作放到多线程中并发处理时会出现问题：某线程select了一条记录但还没来得及update时，另一个线程仍然可能会进来select到同一条记录。<br><br>]]></description><content:encoded><![CDATA[在使用SQL时，大都会遇到这样的问题，你Update一条记录时，需要通过Select来检索出其值或条件，然后在通过这个值来执行修改操作。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;但当以上操作放到多线程中并发处理时会出现问题：某线程select了一条记录但还没来得及update时，另一个线程仍然可能会进来select到同一条记录。<br><br><br>一般解决办法就是使用锁和事物的联合机制：<br><br>如：&nbsp;<br><br>1.&nbsp;把select放在事务中,&nbsp;否则select完成,&nbsp;锁就释放了<br>2.&nbsp;要阻止另一个select&nbsp;,&nbsp;则要手工加锁,&nbsp;select&nbsp;默认是共享锁,&nbsp;select之间的共享锁是不冲突的,&nbsp;所以,&nbsp;如果只是共享锁,&nbsp;即使锁没有释放,&nbsp;另一个select一样可以下共享锁,&nbsp;从而select出数据&nbsp;<br><br><br>BEGIN&nbsp;TRAN<br>SELECT&nbsp;*&nbsp;FROM&nbsp;table&nbsp;WITH(TABLOCKX)&nbsp;<br><br><br>或者&nbsp;SELECT&nbsp;*&nbsp;FROM&nbsp;table&nbsp;WITH(UPDLOCK,&nbsp;READPAST)&nbsp;具体情况而定。<br><br>UPDATE&nbsp;....<br>COMMIT&nbsp;TRAN<br><br><br>锁描述：<br>HOLDLOCK：将共享锁保留到事务完成，而不是在相应的表、行或数据页不再需要时就立即释放锁。HOLDLOCK&nbsp;等同于&nbsp;SERIALIZABLE。&nbsp;<br>NOLOCK&nbsp;不要发出共享锁，并且不要提供排它锁。当此选项生效时，可能会读取未提交的事务或一组在读取中间回滚的页面。有可能发生脏读。仅应用于&nbsp;SELECT&nbsp;语句。&nbsp;<br>PAGLOCK：在通常使用单个表锁的地方采用页锁。&nbsp;<br>READCOMMITTED：用与运行在提交读隔离级别的事务相同的锁语义执行扫描。默认情况下，SQL&nbsp;Server&nbsp;2000&nbsp;在此隔离级别上操作。&nbsp;<br>READPAST：跳过锁定行。此选项导致事务跳过由其它事务锁定的行（这些行平常会显示在结果集内），而不是阻塞该事务，使其等待其它事务释放在这些行上的锁。&nbsp;READPAST&nbsp;锁提示仅适用于运行在提交读隔离级别的事务，并且只在行级锁之后读取。仅适用于&nbsp;SELECT&nbsp;语句。&nbsp;<br>READUNCOMMITTED：等同于&nbsp;NOLOCK。&nbsp;<br>REPEATABLEREAD：用与运行在可重复读隔离级别的事务相同的锁语义执行扫描。&nbsp;<br>ROWLOCK：使用行级锁，而不使用粒度更粗的页级锁和表级锁。&nbsp;<br>SERIALIZABLE：用与运行在可串行读隔离级别的事务相同的锁语义执行扫描。等同于&nbsp;HOLDLOCK。&nbsp;<br>TABLOCK：使用表锁代替粒度更细的行级锁或页级锁。在语句结束前，SQL&nbsp;Server&nbsp;一直持有该锁。但是，如果同时指定&nbsp;HOLDLOCK，那么在事务结束之前，锁将被一直持有。&nbsp;<br>TABLOCKX&nbsp;使用表的排它锁。该锁可以防止其它事务读取或更新表，并在语句或事务结束前一直持有。&nbsp;<br>UPDLOCK：读取表时使用更新锁，而不使用共享锁，并将锁一直保留到语句或事务的结束。UPDLOCK：的优点是允许您读取数据（不阻塞其它事务）并在以后更新数据，同时确保自从上次读取数据后数据没有被更改。&nbsp;<br>XLOCK：使用排它锁并一直保持到由语句处理的所有数据上的事务结束时。可以使用&nbsp;PAGLOCK&nbsp;或&nbsp;TABLOCK&nbsp;指定该锁，这种情况下排它锁适用于适当级别的粒度。<br><br>]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=29</link><dc:subject>sqlserver</dc:subject><dc:creator>admin</dc:creator><dc:date>2007-1-10 16:19:41</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=28"><title><![CDATA[sqlserver 事务锁定]]></title><description><![CDATA[declare&nbsp;@a&nbsp;int&nbsp;&nbsp;&nbsp;<br>&nbsp;SET&nbsp;TRANSACTION&nbsp;ISOLATION&nbsp;LEVEL&nbsp;SERIALIZABLE&nbsp;&nbsp;&nbsp;&nbsp;--防止其他事务更新&nbsp;,但可读取<br>&nbsp;&nbsp;begin&nbsp;tran<br>&nbsp;&nbsp;select&nbsp;@a&nbsp;=&nbsp;a&nbsp;from&nbsp;a&nbsp;where&nbsp;id&nbsp;=&nbsp;1<br>&nbsp;&nbsp;&nbsp;&nbsp;waitfor&nbsp;delay&nbsp;&#39;&#39;00:00:10&#39;&#39;]]></description><content:encoded><![CDATA[declare&nbsp;@a&nbsp;int&nbsp;&nbsp;&nbsp;<br>&nbsp;SET&nbsp;TRANSACTION&nbsp;ISOLATION&nbsp;LEVEL&nbsp;SERIALIZABLE&nbsp;&nbsp;&nbsp;&nbsp;--防止其他事务更新&nbsp;,但可读取<br>&nbsp;&nbsp;begin&nbsp;tran<br>&nbsp;&nbsp;select&nbsp;@a&nbsp;=&nbsp;a&nbsp;from&nbsp;a&nbsp;where&nbsp;id&nbsp;=&nbsp;1<br>&nbsp;&nbsp;&nbsp;&nbsp;waitfor&nbsp;delay&nbsp;&#39;00:00:10&#39;<br>&nbsp;&nbsp;&nbsp;&nbsp;update&nbsp;a&nbsp;set&nbsp;a&nbsp;=&nbsp;a&nbsp;+&nbsp;1&nbsp;where&nbsp;id&nbsp;=&nbsp;1<br>&nbsp;&nbsp;commit&nbsp;tran<br>&nbsp;&nbsp;select&nbsp;@a&nbsp;=&nbsp;a&nbsp;from&nbsp;a&nbsp;where&nbsp;id&nbsp;=&nbsp;1<br>&nbsp;&nbsp;print&nbsp;@a<br><br><strong>参数</strong><br>READ&nbsp;COMMITTED<br><br>指定在读取数据时控制共享锁以避免脏读，但数据可在事务结束前更改，从而产生不可重复读取或幻像数据。该选项是&nbsp;SQL&nbsp;Server&nbsp;的默认值。<br><br>READ&nbsp;UNCOMMITTED<br><br>执行脏读或&nbsp;0&nbsp;级隔离锁定，这表示不发出共享锁，也不接受排它锁。当设置该选项时，可以对数据执行未提交读或脏读；在事务结束前可以更改数据内的数值，行也可以出现在数据集中或从数据集消失。该选项的作用与在事务内所有语句中的所有表上设置&nbsp;NOLOCK&nbsp;相同。这是四个隔离级别中限制最小的级别。<br><br>REPEATABLE&nbsp;READ<br><br>锁定查询中使用的所有数据以防止其他用户更新数据，但是其他用户可以将新的幻像行插入数据集，且幻像行包括在当前事务的后续读取中。因为并发低于默认隔离级别，所以应只在必要时才使用该选项。<br><br>SERIALIZABLE<br><br>在数据集上放置一个范围锁，以防止其他用户在事务完成之前更新数据集或将行插入数据集内。这是四个隔离级别中限制最大的级别。因为并发级别较低，所以应只在必要时才使用该选项。该选项的作用与在事务内所有&nbsp;SELECT&nbsp;语句中的所有表上设置&nbsp;HOLDLOCK&nbsp;相同。<br>]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=28</link><dc:subject>sqlserver</dc:subject><dc:creator>admin</dc:creator><dc:date>2007-1-10 15:50:12</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=27"><title><![CDATA[Visual Studio 2005 对 Windows 窗体控件进行线程安全调用]]></title><description><![CDATA[可以通过将&nbsp;CheckForIllegalCrossThreadCalls&nbsp;属性的值设置为&nbsp;false&nbsp;来禁用此异常。这会使控件以与在&nbsp;Visual&nbsp;Studio&nbsp;2003&nbsp;下相同的方式运行。<br>]]></description><content:encoded><![CDATA[可以通过将&nbsp;CheckForIllegalCrossThreadCalls&nbsp;属性的值设置为&nbsp;false&nbsp;来禁用此异常。这会使控件以与在&nbsp;Visual&nbsp;Studio&nbsp;2003&nbsp;下相同的方式运行。<br>]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=27</link><dc:subject>asp.net</dc:subject><dc:creator>admin</dc:creator><dc:date>2006-12-18 17:48:47</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=26"><title><![CDATA[js控制表格]]></title><description><![CDATA[&lt;form&gt;&nbsp;&lt;input&nbsp;type=&quot;button&quot;&nbsp;onclick=&quot;addline()&quot;&nbsp;value=&quot;增加一行&quot;&gt;&nbsp;&lt;table&nbsp;border=&quot;1&quot;&nbsp;id=&quot;test&quot;&gt;&nbsp;&lt;tr&gt;&nbsp;&lt;td&nbsp;colspan=&quot;2&quot;&gt;&lt;input&nbsp;type=&quot;text&quot;&nbsp;name=&quot;tt[]&quot;&gt;&lt;/td&gt;&nbsp;&lt;/tr&gt;&nbsp;&lt;/table&gt;&nbsp;&lt;input&nbsp;type=&quot;submit&quot;&gt;&nbsp;&lt;/form&gt;&nbsp;<br><br>&lt;script&gt;&nbsp;function&nbsp;addline(content){&nbsp;newline=document.all.test.insertRow();&nbsp;newline.insertCell().innerHTML=&#39;&#39;&lt;input&nbsp;type=&quot;text&quot;&nbsp;name=&quot;tt[]&quot;&gt;&lt;input&nbsp;type=&quot;button&quot;&nbsp;value=&quot;删除此行&quot;&nbsp;onclick=&quot;del()&quot;&gt;&#39;&#39;&nbsp;}&nbsp;function&nbsp;del(){&nbsp;document.all.test.deleteRow(window.event.srcElement.parentElement.parentElement.rowIndex);&nbsp;}&nbsp;&lt;/script&gt;]]></description><content:encoded><![CDATA[&lt;form&gt;&nbsp;&lt;input&nbsp;type=&quot;button&quot;&nbsp;onclick=&quot;addline()&quot;&nbsp;value=&quot;增加一行&quot;&gt;&nbsp;&lt;table&nbsp;border=&quot;1&quot;&nbsp;id=&quot;test&quot;&gt;&nbsp;&lt;tr&gt;&nbsp;&lt;td&nbsp;colspan=&quot;2&quot;&gt;&lt;input&nbsp;type=&quot;text&quot;&nbsp;name=&quot;tt[]&quot;&gt;&lt;/td&gt;&nbsp;&lt;/tr&gt;&nbsp;&lt;/table&gt;&nbsp;&lt;input&nbsp;type=&quot;submit&quot;&gt;&nbsp;&lt;/form&gt;&nbsp;<br><br>&lt;script&gt;&nbsp;function&nbsp;addline(content){&nbsp;newline=document.all.test.insertRow();&nbsp;newline.insertCell().innerHTML=&#39;&lt;input&nbsp;type=&quot;text&quot;&nbsp;name=&quot;tt[]&quot;&gt;&lt;input&nbsp;type=&quot;button&quot;&nbsp;value=&quot;删除此行&quot;&nbsp;onclick=&quot;del()&quot;&gt;&#39;&nbsp;}&nbsp;function&nbsp;del(){&nbsp;document.all.test.deleteRow(window.event.srcElement.parentElement.parentElement.rowIndex);&nbsp;}&nbsp;&lt;/script&gt;]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=26</link><dc:subject>javascript</dc:subject><dc:creator>admin</dc:creator><dc:date>2006-12-14 11:48:40</dc:date></item><item rdf:about="http://www.4vsky.com/blogview.asp?logID=25"><title><![CDATA[处理死锁]]></title><description><![CDATA[/*--处理死锁<br><br>&nbsp;&nbsp;&nbsp;&nbsp;查看当前进程,或死锁进程,并能自动杀掉死进程<br><br>&nbsp;&nbsp;&nbsp;&nbsp;因为是针对死的,所以如果有死锁进程,只能查看死锁进程]]></description><content:encoded><![CDATA[/*--处理死锁<br><br>&nbsp;&nbsp;&nbsp;&nbsp;查看当前进程,或死锁进程,并能自动杀掉死进程<br><br>&nbsp;&nbsp;&nbsp;&nbsp;因为是针对死的,所以如果有死锁进程,只能查看死锁进程<br>&nbsp;&nbsp;&nbsp;&nbsp;当然,你可以通过参数控制,不管有没有死锁,都只查看死锁进程<br><br>&nbsp;&nbsp;&nbsp;&nbsp;感谢:&nbsp;caiyunxia,jiangopen&nbsp;两位提供的参考信息<br><br>--邹建&nbsp;2004.4--*/<br><br>/**//*--调用示例<br><br>&nbsp;&nbsp;&nbsp;&nbsp;exec&nbsp;p_lockinfo<br>--*/<br>create&nbsp;proc&nbsp;p_lockinfo<br>@kill_lock_spid&nbsp;bit=1,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--是否杀掉死锁的进程,1&nbsp;杀掉,&nbsp;0&nbsp;仅显示<br>@show_spid_if_nolock&nbsp;bit=1&nbsp;&nbsp;&nbsp;&nbsp;--如果没有死锁的进程,是否显示正常进程信息,1&nbsp;显示,0&nbsp;不显示<br>as<br>set&nbsp;nocount&nbsp;on<br>declare&nbsp;@count&nbsp;int,@s&nbsp;nvarchar(1000),@i&nbsp;int<br>select&nbsp;id=identity(int,1,1),标志,<br>&nbsp;&nbsp;&nbsp;&nbsp;进程ID=spid,线程ID=kpid,块进程ID=blocked,数据库ID=dbid,<br>&nbsp;&nbsp;&nbsp;&nbsp;数据库名=db_name(dbid),用户ID=uid,用户名=loginame,累计CPU时间=cpu,<br>&nbsp;&nbsp;&nbsp;&nbsp;登陆时间=login_time,打开事务数=open_tran,&nbsp;&nbsp;&nbsp;&nbsp;进程状态=status,<br>&nbsp;&nbsp;&nbsp;&nbsp;工作站名=hostname,应用程序名=program_name,工作站进程ID=hostprocess,<br>&nbsp;&nbsp;&nbsp;&nbsp;域名=nt_domain,网卡地址=net_address<br>into&nbsp;#t&nbsp;from(<br>&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;标志=&#39;死锁的进程&#39;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spid,kpid,a.blocked,dbid,uid,loginame,cpu,login_time,open_tran,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status,hostname,program_name,hostprocess,nt_domain,net_address,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s1=a.spid,s2=0<br>&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;master..sysprocesses&nbsp;a&nbsp;join&nbsp;(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;blocked&nbsp;from&nbsp;master..sysprocesses&nbsp;group&nbsp;by&nbsp;blocked<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)b&nbsp;on&nbsp;a.spid=b.blocked&nbsp;where&nbsp;a.blocked=0<br>&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;all<br>&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;&#39;|_牺牲品_&gt;&#39;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spid,kpid,blocked,dbid,uid,loginame,cpu,login_time,open_tran,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status,hostname,program_name,hostprocess,nt_domain,net_address,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s1=blocked,s2=1<br>&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;master..sysprocesses&nbsp;a&nbsp;where&nbsp;blocked&lt;&gt;0<br>)a&nbsp;order&nbsp;by&nbsp;s1,s2<br><br>select&nbsp;@count=@@rowcount,@i=1<br><br>if&nbsp;@count=0&nbsp;and&nbsp;@show_spid_if_nolock=1<br>begin<br>&nbsp;&nbsp;&nbsp;&nbsp;insert&nbsp;#t<br>&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;标志=&#39;正常的进程&#39;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;spid,kpid,blocked,dbid,db_name(dbid),uid,loginame,cpu,login_time,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;open_tran,status,hostname,program_name,hostprocess,nt_domain,net_address<br>&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;master..sysprocesses<br>&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;@count=@@rowcount<br>end<br><br>if&nbsp;@count&gt;0<br>begin<br>&nbsp;&nbsp;&nbsp;&nbsp;create&nbsp;table&nbsp;#t1(id&nbsp;int&nbsp;identity(1,1),a&nbsp;nvarchar(30),b&nbsp;Int,EventInfo&nbsp;nvarchar(255))<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;@kill_lock_spid=1<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;declare&nbsp;@spid&nbsp;varchar(10),@标志&nbsp;varchar(10)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;@i&lt;=@count<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;@spid=进程ID,@标志=标志&nbsp;from&nbsp;#t&nbsp;where&nbsp;id=@i<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert&nbsp;#t1&nbsp;exec(&#39;dbcc&nbsp;inputbuffer(&#39;+@spid+&#39;)&#39;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;@@rowcount=0&nbsp;insert&nbsp;#t1(a)&nbsp;values(null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;@标志=&#39;死锁的进程&#39;&nbsp;exec(&#39;kill&nbsp;&#39;+@spid)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;@i=@i+1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br>&nbsp;&nbsp;&nbsp;&nbsp;end<br>&nbsp;&nbsp;&nbsp;&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;@i&lt;=@count<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;@s=&#39;dbcc&nbsp;inputbuffer(&#39;+cast(进程ID&nbsp;as&nbsp;varchar)+&#39;)&#39;&nbsp;from&nbsp;#t&nbsp;where&nbsp;id=@i<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;insert&nbsp;#t1&nbsp;exec(@s)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;@@rowcount=0&nbsp;insert&nbsp;#t1(a)&nbsp;values(null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;@i=@i+1<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br>&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;a.*,进程的SQL语句=b.EventInfo<br>&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;#t&nbsp;a&nbsp;join&nbsp;#t1&nbsp;b&nbsp;on&nbsp;a.id=b.id<br>&nbsp;&nbsp;&nbsp;&nbsp;order&nbsp;by&nbsp;进程ID<br>end<br>set&nbsp;nocount&nbsp;off<br><br>GO<br><br><br>--查看<br>if&nbsp;exists&nbsp;(select&nbsp;*&nbsp;from&nbsp;dbo.sysobjects&nbsp;where&nbsp;id&nbsp;=&nbsp;object_id(N&#39;[dbo].[sp_who_lock]&#39;)&nbsp;and&nbsp;OBJECTPROPERTY(id,&nbsp;N&#39;IsProcedure&#39;)&nbsp;=&nbsp;1)<br>drop&nbsp;procedure&nbsp;[dbo].[sp_who_lock]<br>GO<br>use&nbsp;master<br>go<br>create&nbsp;procedure&nbsp;sp_who_lock<br>as<br>begin<br>declare&nbsp;@spid&nbsp;int,@bl&nbsp;int,<br>&nbsp;&nbsp;&nbsp;&nbsp;@intTransactionCountOnEntry&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@intRowcount&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@intCountProperties&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@intCounter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int<br><br>&nbsp;&nbsp;&nbsp;&nbsp;create&nbsp;table&nbsp;#tmp_lock_who&nbsp;(<br>&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;int&nbsp;identity(1,1),<br>&nbsp;&nbsp;&nbsp;&nbsp;spid&nbsp;smallint,<br>&nbsp;&nbsp;&nbsp;&nbsp;bl&nbsp;smallint)<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;@@ERROR&lt;&gt;0&nbsp;RETURN&nbsp;@@ERROR<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;insert&nbsp;into&nbsp;#tmp_lock_who(spid,bl)&nbsp;select&nbsp;&nbsp;0&nbsp;,blocked<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;(select&nbsp;*&nbsp;from&nbsp;sysprocesses&nbsp;where&nbsp;&nbsp;blocked&gt;0&nbsp;)&nbsp;a&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;not&nbsp;exists(select&nbsp;*&nbsp;from&nbsp;(select&nbsp;*&nbsp;from&nbsp;sysprocesses&nbsp;where&nbsp;&nbsp;blocked&gt;0&nbsp;)&nbsp;b&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;a.blocked=spid)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;union&nbsp;select&nbsp;spid,blocked&nbsp;from&nbsp;sysprocesses&nbsp;where&nbsp;&nbsp;blocked&gt;0<br><br>&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;@@ERROR&lt;&gt;0&nbsp;RETURN&nbsp;@@ERROR&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>--&nbsp;找到临时表的记录数<br>&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@intCountProperties&nbsp;=&nbsp;Count(*),@intCounter&nbsp;=&nbsp;1<br>&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;#tmp_lock_who<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;@@ERROR&lt;&gt;0&nbsp;RETURN&nbsp;@@ERROR&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;&nbsp;&nbsp;&nbsp;@intCountProperties=0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;&#39;现在没有阻塞和死锁信息&#39;&nbsp;as&nbsp;message<br><br>--&nbsp;循环开始<br>while&nbsp;@intCounter&nbsp;&lt;=&nbsp;@intCountProperties<br>begin<br>--&nbsp;取第一条记录<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@spid&nbsp;=&nbsp;spid,@bl&nbsp;=&nbsp;bl<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;#tmp_lock_who&nbsp;where&nbsp;Id&nbsp;=&nbsp;@intCounter&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;@spid&nbsp;=0&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;&#39;引起数据库死锁的是:&nbsp;&#39;+&nbsp;CAST(@bl&nbsp;AS&nbsp;VARCHAR(10))&nbsp;+&nbsp;&#39;进程号,其执行的SQL语法如下&#39;<br>&nbsp;else<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;&#39;进程号SPID：&#39;+&nbsp;CAST(@spid&nbsp;AS&nbsp;VARCHAR(10))+&nbsp;&#39;被&#39;&nbsp;+&nbsp;&#39;进程号SPID：&#39;+&nbsp;CAST(@bl&nbsp;AS&nbsp;VARCHAR(10))&nbsp;+&#39;阻塞,其当前进程执行的SQL语法如下&#39;<br>&nbsp;DBCC&nbsp;INPUTBUFFER&nbsp;(@bl&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;&nbsp;&nbsp;&nbsp;<br><br>--&nbsp;循环指针下移<br>&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;@intCounter&nbsp;=&nbsp;@intCounter&nbsp;+&nbsp;1<br>end<br><br><br>drop&nbsp;table&nbsp;#tmp_lock_who<br><br>return&nbsp;0<br>end<br>]]></content:encoded><link>http://www.4vsky.com/blogview.asp?logID=25</link><dc:subject>sqlserver</dc:subject><dc:creator>admin</dc:creator><dc:date>2006-12-12 11:26:33</dc:date></item>
</rdf:Seq>
</items>
</channel>
</rdf:RDF>