您的位置:首页精文荟萃软件资讯 → 在ASP.NET程序中创建唯一序号

在ASP.NET程序中创建唯一序号

时间:2004/10/8 13:20:00来源:本站整理作者:蓝点我要评论(0)


  如果在程序中需要创建全局唯一的序号,那么必须对创建序号的过程进行同步处理,防止多个并发访问时出现相同序号的情况。下面列出几种方法供大家参考。


  利用数据库的方法


  后面的例子都基于MS SQL Server,如果使用Oracle可以直接读取Sequence对象,则不需要进行如此复杂的操作。


  方法1:利用表锁定


  表结构:


create table xtab (seq_id int primary key, create_time datetime)


  存储过程或SQL语句:



begin tran


declare @max_seq int


--读出记录时锁定表


select @max_seq=max(seq_id) from xtab with (TABLOCKX)


set @max_seq = isnull(@max_seq,0)


set @max_seq = @max_seq+1


print @max_seq


insert into xtab values(@max_seq,getDate())


commit


--变量@max_seq 中存放的就是当前产生的序号


  方法2:利用自增字段


  如果利用自增变量可以通过方法1中锁定表,然后再插入记录,并读取最大值的方法。不过下面讲的是通过C#的ADO.NET来插入记录,并读取已经插入的记录的自增字段。


  表结构:


create table xtab_i (seq_id int IDENTITY(1,1) primary key, create_time datetime)


  C#代码,利用时间处理函数在数据被更新时同时读取@@IDENTITY变量的值。完整内容参考:OleDbWrap.cs 文件。



//参数内容:

//szSelectSql = ”select * from xtab_i where seq_id isnull”;

//szTabName = “xtab_i”;

///


/// 通过查询语句 创建DataSet对象,返回的对象用于执行插入操作

///


///

SQL语句

///

表名称

///

用于插入的DataSet对象



public DataSet CreateInsertDataSet_bySelect(string szSelectSql,string szTabName){     

 m_dbAdapter.SelectCommand = new OleDbCommand(szSelectSql, m_dbConn);

 OleDbCommandBuilder cb = new OleDbCommandBuilder(m_dbAdapter);

 DataSet ds = new DataSet();

 m_dbAdapter.Fill(ds, szTabName);

 m_dbAdapter.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated_Inserted);

 return ds;

}

//----------------私有事件处理

///


/// 处理数据插入的更新事件

///


///


///



protected void OnRowUpdated_Inserted(object sender, OleDbRowUpdatedEventArgs args)

{

 OleDbCommand idCMD = new OleDbCommand("SELECT @@IDENTITY", m_dbConn);

 if (args.StatementType == StatementType.Insert) 

 {

  object rObj = idCMD.ExecuteScalar(); 

  if(rObj == null) m_iDbIdentity =-1;

  else if( rObj.ToString() !="") 

   m_iDbIdentity = Int32.Parse(rObj.ToString()); 

  else

   m_iDbIdentity =-1; 

 }

 idCMD.Dispose(); 

 //m_iDbIdentity变量中包含的就是当前插入列的自增字段的值

}


  利用程序控制


  方法1:利用ASP.NET中的Application对象


  利用ASP.NET中的全局HttpApplicationState对象。


  C#代码:



Application.Lock();


Application[“xlock”]=”locked’;


try


{ //必须捕捉异常,避免无法解锁对象


//your Code here


}


catch (Exception e)


{


}


Application[“xlock”]=”unlock”;


  方法2:利用操作系统中的同步对象来实现同步


  在dotNet的框架的System.Threading命名空间下定义了多种用于同步的类,例如:Mutex,Semaphore。下面介绍一下利用互斥对象Mutex来实现同步的方法。


  C#代码:



void Test()

{ //需要引入 System.Threading;

//创建名为MyMutex的互斥对象,如果OS已经创建过同名对象则只是重新获得句柄


Mutex m = new Mutex(false, "MyMutex");

//在10秒内等待取得访问权

boolean getMutex=m.WaitOne(10*1000,false);

if(getMutex)

{ //已经取得访问权

 try

 {

  //必须捕捉异常,避免无法解锁对象

  //Your code here

 }

 catch(Exception e)

 {

 }

 m.ReleaseMutex();

}

else

{

 //没有取得访问权

}


}


  在程序中应该尽量使用Mutex这类可以命名的同步对象以达到创建多个同步对象,对多种资源进行同步的目的。如果要实现多个同入可以使用信号量 Semaphore。


  其他方法:利用lock关键字防止线程并发同一段代码执行


  C#代码:



class CTest 

{

 int balance;

 void Increase() 

 {

  lock (this)

  {

   balance++;

  }

 }

}


  由于ASP.NET程序在IIS中可能配置不同的线程模式,所以在ASP.NET程序尽可能不要使用这种方法同步线程,而在普通的应用程序中是可以使用这种方法。


   附:OleDbWrap.cs ,是一个很简单的封装类,封装了基本的数据库操作。



using System;

using System.Data;

using System.Data.OleDb;


namespace Wyy.Wrap

{

///


/// wDbWrap 说明:完成数据库访问功能

/// 1 创建Connection,Adapter,管理对象内的Conn和Adapter对象

/// 2 通过Select结果集填充Dataset

/// 3 插入

/// 4 更新

///


public class OleDbWrap

{

//--------公共方法

///


/// 在对象被清除时会自动清除 数据库连接对象

///


public OleDbWrap()

{

m_dbConn = new OleDbConnection(DbString);

m_fAutoDelConn = true;

m_dbAdapter = new OleDbDataAdapter();

m_dbConn.Open();

}

///


/// 通过连接字符串构造内部的数据库连接对象

///


///

ADO连接字符串

public OleDbWrap(string strConnection)

{

m_dbConn = new OleDbConnection(strConnection);

m_fAutoDelConn = true;

m_dbAdapter = new OleDbDataAdapter();

m_dbConn.Open();

}

///


/// 通过现有连接构造对象,在对象被清除时不会自动清除 数据库连接对象

///


///

现存的数据库连接对象

public OleDbWrap(OleDbConnection conn)

{

m_dbConn = conn;

m_fAutoDelConn = false;

m_dbAdapter = new OleDbDataAdapter();

//m_dbConn.Open();

}

public virtual void Dispose()

{

m_dbAdapter.Dispose();

if(m_fAutoDelConn)

{

m_dbConn.Close();

m_dbConn.Dispose();

}

}

///


/// 通过SQL语句创建DataReader对象

///


///

SQL语句

///

DataReader对象


public OleDbDataReader CreateDataReader(string szSql)

{

OleDbCommand cmd = new OleDbCommand(szSql,m_dbConn);

OleDbDataReader dr= cmd.ExecuteReader();

cmd.Dispose();

return dr;

}

///


/// 通过SQL查询语句,返回第一行结果,可以用于执行类似与Select Count(*)的语句

///


///

SQL语句

///

返回对象


public object ExecuteScalar(string szSql)

{

OleDbCommand idCMD = new OleDbCommand(szSql, m_dbConn);

object rObj = idCMD.ExecuteScalar();

idCMD.Dispose();

return rObj;

}

///


/// 调用OleDbCommand 的 ExecuteNonQuery

///


///


///


public int ExecuteNonQuery(string szSql)

{

OleDbCommand idCMD = new OleDbCommand(szSql, m_dbConn);

int iRet = idCMD.ExecuteNonQuery();

idCMD.Dispose();

return iRet;

}

///


/// 创建查询用DataSet对象

///


///

查询SQL语句

///

表名称

///

已经被填充的DataSet对象


public DataSet CreateSelectDataSet(string szSql,string szTabName)

{

m_dbAdapter.SelectCommand = new OleDbCommand(szSql,m_dbConn);

DataSet ds = new DataSet();

m_dbAdapter.Fill(ds,szTabName);

return ds;

}

///


/// 通过查询语句 创建DataSet对象,返回的对象用于执行插入操作

///


///

SQL语句

///

表名称

///

用于插入的DataSet对象


public DataSet CreateInsertDataSet_bySelect(string szSelectSql,string szTabName)

{

m_dbAdapter.SelectCommand = new OleDbCommand(szSelectSql, m_dbConn);



OleDbCommandBuilder cb = new OleDbCommandBuilder(m_dbAdapter);


DataSet ds = new DataSet();

m_dbAdapter.Fill(ds, szTabName);

m_dbAdapter.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated_Inserted);

return ds;

}

///


/// 通过查询语句 创建DataSet对象,返回的对象用于执行更新操作

///


///

SQL语句

///

表名称

///

用于更新的DataSet对象


public DataSet CreateUpdateDataSet_bySelect(string szSelectSql,string szTabName)

{

m_dbAdapter.SelectCommand = new OleDbCommand(szSelectSql, m_dbConn);



OleDbCommandBuilder cb = new OleDbCommandBuilder(m_dbAdapter);


DataSet ds = new DataSet();

m_dbAdapter.Fill(ds, szTabName);

return ds;

//m_dbAdapter.RowUpdated += new OleDbRowUpdatedEventHandler(OnRowUpdated_Update);

}

//----------------私有事件处理

///


/// 处理数据插入的更新事件

///


///


///


protected void OnRowUpdated_Inserted(object sender, OleDbRowUpdatedEventArgs args)

{

OleDbCommand idCMD = new OleDbCommand("SELECT @@IDENTITY", m_dbConn);



if (args.StatementType == StatementType.Insert)

{

object rObj = idCMD.ExecuteScalar();

if(rObj == null)

m_iDbIdentity =-1;

else if( rObj.ToString() !="")

m_iDbIdentity = Int32.Parse(rObj.ToString());

else

m_iDbIdentity =-1;

}

idCMD.Dispose();

}

//------------公共属性

///


/// 在插入数据后获取新数据行中自增字段的值,目前只能支持一个自增字段

///


public Int32 DbIdentity {get{return m_iDbIdentity;} }

///


/// 数据库连接字符串,保存在web.config文件中节

///


public string DbString {get{return System.Configuration.ConfigurationSettings.AppSettings["dbStr"];}}



//------------公共变量

///


/// 数据库连接

///


public OleDbConnection m_dbConn;

///


/// 查询Adapter

///


public OleDbDataAdapter m_dbAdapter;

public const String m_szRootUrl ="/copathway/toDo/";



//---------- 私有变量

///


/// 保存数据库插入是自增字段的值

///


protected Int32 m_iDbIdentity =-1;

protected bool m_fAutoDelConn = true;

}

}  


相关阅读 Windows错误代码大全 Windows错误代码查询激活windows有什么用Mac QQ和Windows QQ聊天记录怎么合并 Mac QQ和Windows QQ聊天记录Windows 10自动更新怎么关闭 如何关闭Windows 10自动更新windows 10 rs4快速预览版17017下载错误问题Win10秋季创意者更新16291更新了什么 win10 16291更新内容windows10秋季创意者更新时间 windows10秋季创意者更新内容kb3150513补丁更新了什么 Windows 10补丁kb3150513是什么

文章评论
发表评论

热门文章 360快剪辑怎么使用 36金山词霸如何屏幕取词百度收购PPS已敲定!3

最新文章 微信3.6.0测试版更新了微信支付漏洞会造成哪 360快剪辑怎么使用 360快剪辑软件使用方法介酷骑单车是什么 酷骑单车有什么用Apple pay与支付宝有什么区别 Apple pay与贝贝特卖是正品吗 贝贝特卖网可靠吗

人气排行 xp系统停止服务怎么办?xp系统升级win7系统方电脑闹钟怎么设置 win7电脑闹钟怎么设置office2013安装教程图解:手把手教你安装与qq影音闪退怎么办 QQ影音闪退解决方法VeryCD镜像网站逐个数,电驴资料库全集同步推是什么?同步推使用方法介绍QQ2012什么时候出 最新版下载EDiary——一款好用的电子日记本