2009-01-29 19 views
11

Tôi có danh sách 10 đối tượng dữ liệu mà tôi muốn chèn/cập nhật cơ sở dữ liệu bằng NHibernate. Nếu một ném một ngoại lệ (nói một vi phạm chính tiểu học) tôi muốn vẫn chèn/cập nhật khác 9. Tôi cuộn từng hoạt động đối tượng vào giao dịch nguyên tử của riêng mình, và quay trở lại giao dịch nếu có một ngoại lệ. Vấn đề là nếu một giao dịch gây ra một ngoại lệ và được quay trở lại, trên giao dịch tiếp theo Nhibernate than phiền với lỗi: null id trong Nexus.Data.PortfolioCorporateĐơn nhập cảnh (không xả phiên sau khi ngoại lệ xảy ra)Nhibernate: Xử lý ngoại lệ ITransaction Vì vậy, giao dịch mới có thể tiếp tục với cùng một ISession

Chương trình chính của tôi rất đơn giản. Nó tạo ra một phiên từ một sessionfactory, tạo ra lớp truy cập dữ liệu, một số làm việc trên các đối tượng dữ liệu và sau đó cố gắng lưu các đối tượng dữ liệu đó vào cơ sở dữ liệu.

sessionsManager = new NHibernateSessionManager(); 
     session = sessionsManager.GetSession(); 
     DALC = new NHibernateDataProvider(session); 

     … 

     foreach (var pce in pces) 
     { 
      try 
      { 
       DALC.UpdateOrAddObject<PortfolioCorporateEntity>(pce); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Could not add Corporate Entity ID " + pce.CorporateEntity.CorporateEntityID.ToString()); 
      } 

     } 

Đây là bản cập nhậtThêm thủ tục trong lớp Nhibernate Data Access, được gọi là 10 lần cho 10 đối tượng.

public void UpdateOrAddObject<T>(T workObject) 
{ 
    using (ITransaction tx = mSession.BeginTransaction) { 
     try { 
      mSession.SaveOrUpdate(workObject); 
      mSession.Flush(); 
      tx.Commit(); 
     } 
     catch (Exception ex) { 
      tx.Rollback(); 
      throw; 
     } 
    } 
} 

Để làm rõ vấn đề, phiên được khởi tạo bởi chương trình gọi và được chuyển đến đối tượng Lớp truy cập dữ liệu, hàm tạo bên dưới.

public NHibernateDataProvider(ISession session) 
{ 
    mSession = session; 
} 

này hoạt động tốt, ngoại trừ sau khi ngoại lệ, nó nói không tuôn phiên sau khi ngoại lệ. Tôi không chắc chắn lý do tại sao - giao dịch được cuộn lại độc đáo và cơ sở dữ liệu phải sẵn sàng chấp nhận một giao dịch khác không? Tôi đang làm gì sai?

Trả lời

9

Không thể sử dụng lại phiên NHibernate sau khi ngoại lệ được ném. Quoting the documentation:

If the ISession throws an exception you should immediately rollback the 
transaction, call ISession.Close() and discard the ISession instance. 
Certain methods of ISession will not leave the session in a consistent state. 

Vì vậy, câu trả lời là bạn không thể làm những gì bạn đang cố gắng để làm. Bạn cần phải tạo phiên mới và thử lại các bản cập nhật tại đó.

0

Cảm ơn bạn đã trả lời. Chỉ muốn chắc chắn rằng nó được thực hiện đúng. Những gì bạn đang nói là việc xử lý lỗi của tôi phải được thay đổi đơn giản thành:

 foreach (var pce in pces) 
     { 
      try 
      { 
       DALC.UpdateOrAddObject<PortfolioCorporateEntity>(pce); 
      } 
      catch (Exception ex) 
      { 
       Console.WriteLine("Could not add Corporate Entity ID " + pce.CorporateEntity.CorporateEntityID.ToString()); 

       session.Close(); 
       session = sessionsManager.GetSession(); 
       DALC.Session = session; 

      } 
     } 

Có vẻ như điều này chỉ hoạt động tốt. Cảm ơn.

+0

Từ những gì bạn được đăng, mà có vẻ như nó sẽ làm việc. Nó thực sự phụ thuộc vào việc thực hiện lớp DALC của bạn. –

+0

Có khác nhau giữa giải pháp này (session.Close/reopen) và giải pháp trên chỉ với session.Clear()? – dataCore

6

tôi xóa phiên và nó tiếp tục bình thường

 

ISession session = NHibernateHelper.Session; 
using (ITransaction transaction = session.BeginTransaction()) 
{ 
    try 
    { 
     session.Update(user, user.UserID); 
     transaction.Commit(); 
    } 
    catch (Exception ex) 
    { 
     transaction.Rollback(); 
     session.Clear(); 
     throw new DALException("Cannot update user", ex); 
    } 
} 
 
+0

Hoạt động! Đây có phải là cách tiết kiệm không? Chỉ cần sử dụng "session.Clear()" để ổn định phiên? – dataCore

+0

@sh_kamalh Cảm ơn bạn đời! Tôi cũng phải đối mặt với cùng một vấn đề và tìm kiếm một giải pháp đơn giản như thế này. – shahjahan

Các vấn đề liên quan