2012-03-05 36 views
0

我有兩個班,行程爲家長和門票爲孩子NHibernate的:插入新的子數據和堅持父母在交易

public class Trip : Entity 
{ 
    public string TripNo { get; set; } 
    public string IsActive { get; set; } 
} 

public class Ticket : Entity 
{ 
    public Trip Trip { get; set; } 
    public string TicketNo { get; set; } 
} 

在一個事務中,我如何確保新的票務加入與Trip.IsActive爲真,不會在其他交易中修改。如果我檢查旅程的版本,它仍然可以在其他交易中修改。如果我鎖定了(在選定的旅程中),它將會有性能問題,因爲一秒鐘內有一千張票插入。 謝謝你的所有建議。

+0

從旅行到票一到關係多,多對多或一對一? – 2012-03-05 12:40:32

回答

1
// change class to 
public class Trip : Entity 
{ 
    public int Version { get; private set; } 

    public string TripNo { get; set; } 
    public string IsActive { get; set; } 
} 

// configure using FluentNhibernate Mapping 
// in TripMap 
Version(t => t.Version); 

// use like this 
void AddTicket(string tripno, string ticketNo) 
{ 
    bool interupted = false; 
    do 
    { 
     interupted = false; 
     try 
     { 
      using(var tx = session.BeginTransaction()) 
      { 
       var trip = session.Query<Trip>().Where(t => t.TripNo == tripno && t.IsActive).FirstOrDefault(); 
       if (trip == null) 
        return; 
       var ticket = new Ticket { TicketNo = ticketNo, Trip = trip }; 
       session.SaveOrUpdate(ticket); 
       tx.Commit() 
      } 
     } 
     catch(StaleObjectException) 
     { 
      // someone messed up with the Trip 
      interupted = true; 
     } 
    } while (interupted); 
} 

更新:來證明這一點donwload System.Data.Sqlite.dll並創建一個新ConsoleApp與下面的代碼

var config = Fluently.Configure() 
    .Database(SQLiteConfiguration.Standard.InMemory().ShowSql().FormatSql()) 
    .Mappings(m => m.FluentMappings 
     .Add<TripMap>() 
    ) 
    .BuildConfiguration(); 

var sf = config.BuildSessionFactory(); 

using (var session = sf.OpenSession()) 
using (var session2 = sf.OpenSession(session.Connection)) // use the same connection because inmemory dbs are bound to the connection, nevertheless the session act as if they have different connections 
{ 
    new SchemaExport(config).Execute(true, true, false, session.Connection, null); 

    // fill the database 
    int tripId = session.Save(new Trip { No = "1" }); 
    session.Flush(); 
    session.Clear(); // Clear cache 

    var user1 = session.Get<Trip>(tripId); 
    var user2 = session2.Get<Trip>(tripId); 

    user1.No = 2; 
    user2.No = 3; 

    session.Flush(); 
    session2.Flush(); // throws StaleObjectException here 
} 
+0

嗯,我忘了改變旅途莫名其妙。否則,NHibernate不會發布更改。我將在明天覆習 – Firo 2012-03-05 17:28:23

+0

您的解決方案顯示,如果在事務中間修改了trip,NHibernate將拋出StaleObjectException。如何證明它? – hafizishak 2012-03-06 01:27:02