<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <link rel="stylesheet" type="text/css" href="docs.css"> <!--[if gte IE 5]> <link href="docs_ie.css" rel="stylesheet" type="text/css"> <![endif]--> </head> <body><div id="pagecontainer"><table><tr><td width="5"> </td><td><a name="Transactions"></a><br> <a name="outline186"></a><br><h1>8. Transactions</h1><br> Probably you have already wondered how db4o handles concurrent access to a single database. Just as any other DBMS, db4o provides a transaction mechanism. Before we take a look at multiple, perhaps even remote, clients accessing a db4o instance in parallel, we will introduce db4o transaction concepts in isolation.<br> <br> <ul> <a name="outline187"></a><br><h2>8.1. Commit and rollback</h2><br> You may not have noticed it, but we have already been working with transactions from the first chapter on. By definition, you are always working inside a transaction when interacting with db4o. A transaction is implicitly started when you open a container, and the current transaction is implicitly committed when you close it again. So the following code snippet to store a car is semantically identical to the ones we have seen before; it just makes the commit explicit.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// storeCarCommit<br> Pilot pilot = new Pilot("Rubens Barrichello", 99);<br> Car car = new Car("BMW");<br> car.Pilot = pilot;<br> db.Store(car);<br> db.Commit();</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4o.f1.chapter5.TransactionExample", "storeCarCommit")' /></td></tr></table> <br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// listAllCars<br> IObjectSet result = db.QueryByExample(typeof(Car));<br> ListResult(result);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4o.f1.chapter5.TransactionExample", "listAllCars")' /></td></tr></table> <br> <br> However, we can also rollback the current transaction, resetting the state of our database to the last commit point.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// storeCarRollback<br> Pilot pilot = new Pilot("Michael Schumacher", 100);<br> Car car = new Car("Ferrari");<br> car.Pilot = pilot;<br> db.Store(car);<br> db.Rollback();</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4o.f1.chapter5.TransactionExample", "storeCarRollback")' /></td></tr></table> <br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// listAllCars<br> IObjectSet result = db.QueryByExample(typeof(Car));<br> ListResult(result);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4o.f1.chapter5.TransactionExample", "listAllCars")' /></td></tr></table> <br> <br> <a name="outline188"></a><br><h2>8.2. Refresh live objects</h2><br> There's one problem, though: We can roll back our database, but this cannot automagically trigger a rollback for our live objects.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// carSnapshotRollback<br> IObjectSet result = db.QueryByExample(new Car("BMW"));<br> Car car = (Car)result.Next();<br> car.Snapshot();<br> db.Store(car);<br> db.Rollback();<br> Console.WriteLine(car);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4o.f1.chapter5.TransactionExample", "carSnapshotRollback")' /></td></tr></table> <br> <br> We will have to explicitly refresh our live objects when we suspect they may have participated in a rollback transaction.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// carSnapshotRollbackRefresh<br> IObjectSet result=db.QueryByExample(new Car("BMW"));<br> Car car=(Car)result.Next();<br> car.Snapshot();<br> db.Store(car);<br> db.Rollback();<br> db.Ext().Refresh(car, int.MaxValue);<br> Console.WriteLine(car);</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4o.f1.chapter5.TransactionExample", "carSnapshotRollbackRefresh")' /></td></tr></table> <br> <br> What is this IExtObjectContainer construct good for? Well, it provides some functionality that is in itself stable, but the API may still be subject to change. As soon as we are confident that no more changes will occur, <em>ext</em> functionality will be transferred to the common IObjectContainer API. <br> <br> Finally, we clean up again.<br> <br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>// deleteAll<br> IObjectSet result = db.QueryByExample(typeof(Object));<br> foreach (object item in result)<br> {<br> db.Delete(item);<br> }</code></td><td class="lg" align="left" valign="bottom" width=43><input type='button' class='button' value='Run' onclick='window.external.RunExample("com.db4o.f1.Util", "deleteAll")' /></td></tr></table> <br> <br> <a name="outline189"></a><br><h2>8.3. Conclusion</h2><br> We have seen how transactions work for a single client. In the <a href="ClientServer.html#ClientServer">Client/Server chapter</a> we will see how the transaction concept extends to multiple clients, whether they are located within the same runtime or on a remote machine.<br> <br> Let't first revisit Activation again in the <a href="TransparentActivation.html#TransparentActivation">next chapter</a> and take a look at how db4o can take care of our Object lifecycle automatically. <br> <br> <a name="outline190"></a><br><h2>8.4. Full source</h2><br> <table width="100%" cellpadding="3" cellspacing="0" border="0"><tr><td class="lg"> <code>using System;<br> using System.IO;<br> using Db4objects.Db4o;<br> namespace Db4objects.Db4o.Tutorial.F1.Chapter5<br> {<br> public class TransactionExample : Util<br> {<br> public static void Main(string[] args)<br> {<br> File.Delete(Util.YapFileName);<br> IObjectContainer db=Db4oFactory.OpenFile(Util.YapFileName);<br> try<br> {<br> StoreCarCommit(db);<br> db.Close();<br> db = Db4oFactory.OpenFile(Util.YapFileName);<br> ListAllCars(db);<br> StoreCarRollback(db);<br> db.Close();<br> db = Db4oFactory.OpenFile(Util.YapFileName);<br> ListAllCars(db);<br> CarSnapshotRollback(db);<br> CarSnapshotRollbackRefresh(db);<br> }<br> finally<br> {<br> db.Close();<br> }<br> }<br> <br> public static void StoreCarCommit(IObjectContainer db)<br> {<br> Pilot pilot = new Pilot("Rubens Barrichello", 99);<br> Car car = new Car("BMW");<br> car.Pilot = pilot;<br> db.Store(car);<br> db.Commit();<br> }<br> <br> public static void ListAllCars(IObjectContainer db)<br> {<br> IObjectSet result = db.QueryByExample(typeof(Car));<br> ListResult(result);<br> }<br> <br> public static void StoreCarRollback(IObjectContainer db)<br> {<br> Pilot pilot = new Pilot("Michael Schumacher", 100);<br> Car car = new Car("Ferrari");<br> car.Pilot = pilot;<br> db.Store(car);<br> db.Rollback();<br> }<br> <br> public static void CarSnapshotRollback(IObjectContainer db)<br> {<br> IObjectSet result = db.QueryByExample(new Car("BMW"));<br> Car car = (Car)result.Next();<br> car.Snapshot();<br> db.Store(car);<br> db.Rollback();<br> Console.WriteLine(car);<br> }<br> <br> public static void CarSnapshotRollbackRefresh(IObjectContainer db)<br> {<br> IObjectSet result=db.QueryByExample(new Car("BMW"));<br> Car car=(Car)result.Next();<br> car.Snapshot();<br> db.Store(car);<br> db.Rollback();<br> db.Ext().Refresh(car, int.MaxValue);<br> Console.WriteLine(car);<br> }<br> }<br> }<br> </code></td></tr></table> <br> <br><br><br><p align="center"><a href="http://www.db4o.com/" target=_top><small>www.db4o.com</small></a></p><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br></td></tr></table></div></body></html>