The basic usage of this module is to generate a unique ID to replace the use of your database's SEQUENCE
of auto_increment field.
INIT
First, you need to create the sequence object:
use DBIx::Sequence;
my $sequence = new DBIx::Sequence({
db_user => 'scott',
db_pw => 'tiger',
db_dsn => 'dbi:mysql:scottdb',
allow_id_reuse => 1,
});
DBIx::Sequence can be used to manage multiple sets of ID's (perhaps you could have one dataset per table,
or one and only one dataset). This permits you to handle multiple applications with the same sequence
class. The dataset is normally simply a token string that represents your ID set. If the dataset does
not exists, DBIx::Sequence will create automagically for you. No special steps are involved in the
creation of a dataset.
The arguments contains the database informations, db_user, db_pw and db_dsn and are stored in a hash
reference.
At this point, the object has pre cached all of the SQL that will be used to generate the spin locker
race. It is normally a good idea to have a shared sequence object (especially) under mod_perl to save the
prepare overhead. The 'allow_id_reuse' argument can be passed to the constructor to either allow the use
of the Release() or deny it. (True value makes it allowed)
GETTINGTHENEXTID
To get the next id, you simpy have to use the Next() method of your sequence while specifying the dataset
you are getting the next id for.
my $next_id = $sequence->Next($dataset);
RELEASINGID'S.
Generated ID's can be _explicitly_ released in your application. When an ID is released, the sequence
will be able to give this id back to you throught the Next() method.
This is how it is done:
$sequence->Release($dataset, $id);
Note:
You must use release only when you are _CERTAIN_ that your ID is not used anymore and that you want it to
be recycled. The Spin Locking mechanism will also take place on released id's to ensure that no two
processes can get the same ID.
PERMANENTLYREMOVINGADATASET
To make DBIx::Sequence forget about an existing dataset, you need to use the Delete_Dataset() method.
$sequence->Delete_Dataset($dataset);
This will clear all state and existence for this dataset and will also clear it's released id's. Note
that if your application still uses this dataset, it will be automatically recreated blank.
BOOTSTRAPPINGADATASETFROMEXISTINGDATA
It is possible to sync the state of a DBIx::Sequence dataset by using the Bootstrap() method.
$sequence->Bootstrap('my_dataset','my_bootstrap_table','my_primary_field');
Bootstrap() takes 3 arguments.
• The dataset to bootstrap
• The table from wich you will bootstrap
• The field in the bootstrap table that will be used to bootstrap the dataset.
Bootstrap will then sync up the DBIx::Sequence's state with the maximum id of the 'my_primary_field' in
'my_bootstrap_table'. The bootstrap field must be a numeric field as you can suspect. The SQL function
MAX() will be called on it during the bootstrap process.
Note: The bootstrap method _can_ be used at runtime since it will initiate a race for updating the value
thus following the same algorithm. It is recommended though that you use Bootstrap() when no other
concurrent processes are requesting id's.
OVERLOADING
It is possible to create an overloaded class of DBIx::Sequence. This permits you to create a
DBIx::Sequence that has different properties than the orignal one. The only thing you really have to
overload to modify the behaviour of DBIx::Sequence are some constants:
• STATE_TABLE : Defines the table used by DBIx::Sequence to store dataset's states.
• RELEASE_TABLE : Defines the table used by DBIx::Sequence to store released id's.
• COLUMN_PREFIX : A string to be prepended to every column in the internal SQL statements.
• DEFAULT_INIT_VALUE : Value used to initialize a dataset when it is first created.
• DEFAULT_ALLOW_ID_REUSE : When set to true, will allow the use of Release() if not specified in the
constructor. (allow_id_reuse)
• DEBUG_LEVEL : When set to true, will enable debugging to STDERR.
So it is very easy to specify the behaviour of DBIx::Sequence that you wish to use by creating an
overloaded class.
Also, a very important method to overload is the getDbh() method. This is the function that returns the
database handle to the DBIx::Sequence. Your overloaded class should redefine the getDbh method.
Overloading getDbh will make your sequence class integrate more cleanly with your application.
i.e.
package MySequence;
use DBI;
use DBIx::Sequence;
use vars qw(@ISA);
@ISA = qw(DBIx::Sequence);
use constant STATE_TABLE => 'my_state_table';
use constant RELEASE_TABLE => 'my_release_table';
use constant COLUMN_PREFIX => '';
use constant DEFAULT_INIT_VALUE => '100';
use constant DEFAULT_ALLOW_ID_REUSE => 1;
use constant DEBUG_LEVEL => 0;
sub getDbh
{
my $self = shift;
return MyApplication::MyDBModule::getDbh();
}
1;
Then, your code can use this class for its sequencing. Notice that since we overloaded getDbh(), we don't
need to pass a second parameter to new().
use MySequence;
my $sequence = new MySequence();
my $next_id = $sequence->Next($dataset);