IOC用のNhibernateとCastleで.Netを使用しています(すべてのサービスとリポジトリ用)。最近の展開で何か奇妙なことが起こり始めており、問題を追跡するのに苦労しています。
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 呼び出し) を呼び出し続けているようです. この問題が発生していると思われるサーバーの 1 つで 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;
}
}
}
}
}