您的位置:首页 > 其它

11.38 CastleActiveRecord中如何保证多线程并发操作的安全与成功?

2011-10-13 12:59 423 查看
在多线程并发操作环境中,对数据库的操作也必须注意防止并发控制不适当导致数据混乱,目前已经遇到的情况有:

线程1在保存 A 的数据,未使用 事务性会话,同时线程2在操作 B 的数据,使用了 事务性会话,得到的结果是:线程1 的操作全部丢失,线程2 的操作结果正确保存到了数据库。调试错误时却发现,线程1 的程序在测试时由于是单线程环境,运行完全没有问题,开发人员感到莫名其妙,无从下手。

为了避免以上情况,应坚持按如下规则使用会话:

A、纯查询使用无刷新会话,示例如下:

private void DataPortal_Fetch(PartyListCriteria criteria)

{

RaiseListChangedEvents = false;

using (new Castle.ActiveRecord.SessionScope(Castle.ActiveRecord.FlushAction.Never))

{

//添加查询代码如下:

DALParty[] ps = ps = DALParty.Find(criteria.OwnerID, criteria.Name, true,criteria.MaxResult);

}

RaiseListChangedEvents = true;

}

应为有会话的存在,当通过数据实体对象访问 延迟加载数据的一对多关系中多端数据,不会抛出异常。

B、任何有CUD(增删改)操作时,使用事件性会话,示例如下:

protected override void DataPortal_Update()

{

this.RaiseListChangedEvents = false;

using (Castle.ActiveRecord.TransactionScope trans = new Castle.ActiveRecord.TransactionScope())

{

try

{

foreach (var item in DeletedList)

{

item.Child_DeleteSelf(this);

}

DeletedList.Clear();

foreach (var item in this)

{

if (item.IsNew && item.IsValid)

{

item.Child_Insert(this);

}

else if (item.IsDirty && item.IsSavable)

{

item.Child_Update(this);

}

}

trans.VoteCommit();

}

catch (Exception ee)

{

trans.VoteRollBack();

ILog log = LogManager.GetLogger(this.GetType());

log.Error(ee.ToString());

throw ee;

}

}

this.RaiseListChangedEvents = true;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: