Refactoring Database Access in Marauroa: Difference between revisions

From Arianne
Jump to navigation Jump to search
Content deleted Content added
imported>Hendrik Brummermann
included design image
imported>Hendrik Brummermann
started a faq
Line 18: Line 18:


[[Image:Marauroa.server.game.db.png]]
[[Image:Marauroa.server.game.db.png]]

== FAQ ==

=== Where did IDatabase / JDBCDatabase go? ===

It was replaced by smaller classes specialized on one task each. They can be found in the package <code>marauroa.server.game.db</code> ending with "DAO".

=== What are those new ...DAO classes? How do they work? ===

They are "data access object". The basic idea is and has been from the start that the database related code is not in the original classes but at some central point outside the game logic. This used to be JDBCDatabase but one single class for all database operations is very unhandy. So JDBCDatabase has been splitted into a number of small classes focused on one area each: AccountDAO, CharacterDAO, GameEventDAO...

These classes replace the old IDatabase / JDBCDatabase and do the database stuff. All of their methods have two signatures: One with gets an DBTransaction object as first parameter and one without. This is for your convenience: In most cases it those functions are not part of a larger context so you do not have to care about transactions at all because the DAO-classes do the transaction handling on their own. There are, however, a small number of cases in which you want to do multiple calls to DAOs in one single transactions. In this case you get a DBTransaction from the TransactionPool and provide it as first parameter to DAO-methods. After you are done you must either commit or rollback your changes with the appropriate methods in the class TransactionPool.

=== I have extended the JDBCDatabase class. How does this work with DAOs? ===

DAO classes should never be instantiated directly. Instead you should (and marauroa does) use the DAORegistry. This allows you to write a subclass of a DAO provided by marauroa and register it instead. If you are familiar with Spring, this is a similar concept. But without all the bulk of xml configuration files, parameter injection and interfaces with only one single implementation.

Imagine you want to subclass the CharacterDAO with your class SomeGameCharaterDAO:
public class SomeGameCharacterDAO extends CharacterDAO {
...

You simply register it as
DAORegistry.get().register(CharacterDAO.class, new SomeGameCharaterDAO());
Note: In the register call the first parameter is the parent clase you want to replace.

Revision as of 22:42, 10 July 2009

At the moment database access in marauroa is designed for a single thread application. While this does work most of the time in turn based games (yes, Stendhal is turned based internally), it prevents doing non time critical stuff in another thread. In Stendhal we have the problem that any update or delete operation to the gameEvents table that takes more than a couple of seconds kills the server.

Requirements

Hard Requirements

  • multi thread support
  • parallel transactions in different threads

Would be nice

  • a package of small classes instead of huge JDBCDatabase / StendhalPlayerDatabase
  • an small abstraction layer to support different databases beside mysql (small as in "not hibernate")
  • no extra dependencies on new libraries
  • easier way to include variables into sql statements

Design

FAQ

Where did IDatabase / JDBCDatabase go?

It was replaced by smaller classes specialized on one task each. They can be found in the package marauroa.server.game.db ending with "DAO".

What are those new ...DAO classes? How do they work?

They are "data access object". The basic idea is and has been from the start that the database related code is not in the original classes but at some central point outside the game logic. This used to be JDBCDatabase but one single class for all database operations is very unhandy. So JDBCDatabase has been splitted into a number of small classes focused on one area each: AccountDAO, CharacterDAO, GameEventDAO...

These classes replace the old IDatabase / JDBCDatabase and do the database stuff. All of their methods have two signatures: One with gets an DBTransaction object as first parameter and one without. This is for your convenience: In most cases it those functions are not part of a larger context so you do not have to care about transactions at all because the DAO-classes do the transaction handling on their own. There are, however, a small number of cases in which you want to do multiple calls to DAOs in one single transactions. In this case you get a DBTransaction from the TransactionPool and provide it as first parameter to DAO-methods. After you are done you must either commit or rollback your changes with the appropriate methods in the class TransactionPool.

I have extended the JDBCDatabase class. How does this work with DAOs?

DAO classes should never be instantiated directly. Instead you should (and marauroa does) use the DAORegistry. This allows you to write a subclass of a DAO provided by marauroa and register it instead. If you are familiar with Spring, this is a similar concept. But without all the bulk of xml configuration files, parameter injection and interfaces with only one single implementation.

Imagine you want to subclass the CharacterDAO with your class SomeGameCharaterDAO:

    public class SomeGameCharacterDAO extends CharacterDAO {
    ...

You simply register it as

    DAORegistry.get().register(CharacterDAO.class, new SomeGameCharaterDAO());

Note: In the register call the first parameter is the parent clase you want to replace.