利用事物(隔离级别)+锁方式串行化保证在高并发环境下数据的一致性代码
根据表结构,说明多个事物操作的是同一份数据。
先上代码:
/// <summary>
/// 从数据库获取 UniqueID
/// </summary>
/// <returns></returns>
private int[] GetUniqueIDForSimple(string KeyName, int Count)
{
int[] result = new int[]{0, 0};
OracleConnection conn = new OracleConnection("UID=*;PWD=*;Data Source=*");
OracleTransaction tran = null;
DateTime Start;
DateTime End;
try
{
conn.Open();
tran = conn.BeginTransaction(IsolationLevel.ReadCommitted);
///记录开开始时间
Start = DateTime.Now;
ShowMessage("ThreadName:" + Thread.CurrentThread.Name + ", StartDateTime:" + Start);
OracleCommand updateCmd = new OracleCommand("Update UniqueIDs Set KeyValue = KeyValue + " + Count + " Where KeyName='" + KeyName + "'", conn, tran);
int rowsAffected = updateCmd.ExecuteNonQuery();
///记录结束时间
End = DateTime.Now;
TimeSpan span = End - Start;
///由于事务提交或者回滚是在 6 秒钟以后,因此这里应该基本都是等待 6秒
ShowMessage("ThreadName:" + Thread.CurrentThread.Name + ", 等待更新时间:" + span.TotalMilliseconds + "ms");
///更新以后等待3秒
Thread.Sleep(3000);
OracleCommand selectCmd = new OracleCommand("Select KeyValue From UniqueIDs Where KeyName = '" + KeyName + "'", conn, tran);
object keyValueObj = selectCmd.ExecuteScalar();
///查询以后等待3秒
Thread.Sleep(3000);
tran.Commit();
if (keyValueObj != null)
{
result[1] = Convert.ToInt32(keyValueObj) - 1;
result[0] = result[1] - Count + 1;
}
return result;
}
catch (Exception ex)
{
if (tran != null)
tran.Rollback();
return result;
}
finally
{
conn.Close();
}
}
由于外部系统统一调用这个方法开启事务来获取uniqueid, 这里用一个小技巧来保证串行化(保证同一份数据在某一刻加上排他锁仅供一事物所用其他事物等待)先执行更新锁定数据,再执行查询 ,否则会出现并发冲突产生相同滴数据
作者:ChenLuLouis
出处:http://www.cnblogs.com/chenlulouis/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-chenlulouisBlog。
posted on 2010-12-09 14:35 chenlulouis 阅读(2298) 评论(4) 编辑 收藏 举报