我们将 .Net 与 Nhibernate 和 Castle 用于 IOC(用于所有服务和存储库)。最近的部署开始发生一些奇怪的事情,我无法追踪问题。
我们在存储库中有以下代码块,在创建 ObjA 后从服务调用:
public void Save(IList<ObjA> listA, IList<ObjB> listB, ObjC c, Objd d) {
using (var session = GetSession()) {
using (var tx = session.BeginTransaction()) {
try {
session.Save(c);
foreach (var a in listA) {
session.Update(a);
}
foreach (var b in listB) {
// unrelated field updates here
session.Save(b);
}
session.Update(d);
if (!tx.WasCommitted) {
tx.Commit();
}
} catch (Exception) {
if (tx != null) {
tx.Rollback();
}
throw;
}
}
}
}
此代码称为在 listA 中传递 1 个 ObjA,在 listB 中传递 1 个 ObjB,再加上 ObjC 和 ObjD。
我们发现随机(大约有一半的时间)我们得到了重复的 ObjB 和 ObjC 记录(这里唯一被创建而不是更新的对象)。由于 ObjC 有一个 datetime 字段,我可以跟踪记录的创建时间,并且有时会在大约 12-18 小时内创建 5-100 条重复记录。这是在数据库中创建 ObjB 和 ObjC 记录的唯一代码。
我以前从未见过这样的事情,似乎有什么东西卡在了内存中并间歇性地调用这个函数(或 Nhibernate 调用)。我在其中一个似乎存在此问题的服务器上重新启动了 IIS,问题停止了,但第二天又在另一台服务器上启动。
有没有人对可能导致这种情况的原因有任何想法?Castle 或 Nhibernate 的配置中是否存在可能导致这些调用卡住并重复 12-18 小时(超过 100 次?)?
任何帮助表示赞赏:)
Service(){
_saveLater = null;
CalledByWS(){
CreateObjA();
CreateOtherObjs();
}
CreateObjA(){
//Do a lot of stuff here
var a = new ObjA{ };
listToBeSaved.Add(a, SaveOrUpdate.Save);
//Update other objects & add to the list
if(xyz){
_saveLater.ObjA = a
_saveLater.ObjB = GetObjB(a);
_saveLater.ObjC = GetObjC(a);
}
_repo.SaveOrUpdate(listToBeSaved);
}
CreateOtherObjs(){
if(_saveLater == null) return;
Save(new List<ObjA> {_saveLater.ObjA}, new List<ObjB> {_saveLater.ObjB},
_saveLater.Objc, _saveLater.ObjD); //The original function posted
}
}
Repo(){
SaveOrUpdate(Dictionary<IEntity, SaveOrUpdate> objs){
using (var session = GetSession()){
using (var tx = session.BeginTransaction()) {
try {
foreach (var o in objs) {
if (o.Key == null) continue;
if (o.Value == SaveOrUpdate.Update)
session.Update(o.Key);
else
session.Save(o.Key);
}
if (!tx.WasCommitted) {
tx.Commit();
}
} catch (Exception) {
if (tx != null) {
tx.Rollback();
}
throw;
}
}
}
}
}