Oracle Tips and Tricks — David Fitzjarrell

June 6, 2008

Out Of Sequence

Filed under: General — dfitzjarrell @ 12:51

Confusion over the read-consistency mechanism Oracle employs creates situations which really shouldn’t happen but often do. A common issue is experiencing an ORA-00001 error upon attempting to insert an application-generated key value. Let’s look at why that happens and what needs to be done to correct it.

Oracle’s read-consistency mechanism generates a read-consistent image of table data at the time the query starts execution. If Oracle needs to visit rollback/undo records to construct that image it does so without ‘warning’ the user. Because of this, uncommitted changes to data cannot be ‘seen’ by any session other than the one performing those changes, which means that any number of sessions can only ‘see’ the last committed key value (even though 16 other sessions are attempting to add new data to the table). If, say, 17 sessions are trying desperately to add the same key value only one will succeed (again, providing some OTHER session before that hasn’t added the same value but stopped short of a commit statement) and the rest will experience

ERROR at line %d:
ORA-00001: unique constraint (%s) violated

Let’s look at two simultaneous sessions attempting to use that same methodology. Here’s Session 1:

SQL> --
SQL> -- Create test table
SQL> --
SQL> create table ins_test(keycol number, keyval varchar2(20));

Table created.

SQL>
SQL> --
SQL> -- Add primary key constraint
SQL> --
SQL> alter table ins_test add constraint ins_test_pk primary key (keycol);

Table altered.

SQL>
SQL> --
SQL> -- Insert data
SQL> --
SQL> insert all
  2  into ins_test
  3  (keycol, keyval)
  4  values
  5  (1, 'First value')
  6  into ins_test
  7  (keycol, keyval)
  8  values
  9  (2, 'Second value')
 10  into ins_test
 11  (keycol, keyval)
 12  values
 13  (3, 'Third value')
 14  into ins_test
 15  (keycol, keyval)
 16  values
 17  (4, 'Fourth value')
 18  into ins_test
 19  (keycol, keyval)
 20  values
 21  (5, 'Fifth value')
 22  into ins_test
 23  (keycol, keyval)
 24  values
 25  (6, 'Sixth value')
 26  select * from dual;

6 rows created.

SQL>
SQL> --
SQL> -- Commit changes
SQL> --
SQL> commit;

Commit complete.

SQL>
SQL> --
SQL> -- Start questionable process to
SQL> -- insert more data based upon
SQL> -- current max(keycol) value
SQL> --
SQL>
SQL> --
SQL> -- Set a variable to reuse the returned
SQL> -- max value
SQL> --
SQL> --
SQL> -- Rather dumb idea as the max() from
SQL> -- any query will miss any new values
SQL> -- inserted by other sessions and not
SQL> -- yet committed
SQL> --
SQL> column maxval new_value next_key
SQL>
SQL> --
SQL> -- Return current max(keycol)
SQL> --
SQL> -- Not reliable in the least
SQL> -- unless there is only one user
SQL> -- ever on the system, and it's
SQL> -- you
SQL> --
SQL> select max(keycol) maxval from ins_test;

    MAXVAL
----------
         6

SQL>
SQL> --
SQL> -- Use the saved value for the next insert
SQL> --
SQL> -- Not a good idea
SQL> --
SQL> -- Using a sequence and a trigger is far
SQL> -- more reliable and recommended
SQL> --
SQL> insert into ins_test (keycol, keyval)
  2  values (&next_key + 1, 'Next value in line');
old   2: values (&next_key + 1, 'Next value in line')
new   2: values (         6 + 1, 'Next value in line')

1 row created.

SQL>
SQL> --
SQL> -- Wait for a minute so a second insert of this
SQL> -- same type can occur from a different session
SQL> --
SQL>
SQL> exec dbms_lock.sleep(60);

PL/SQL procedure successfully completed.

Now, while the first session waits we try the same thing from Session 2:

SQL> --
SQL> -- Start questionable process to
SQL> -- insert more data based upon
SQL> -- current max(keycol) value
SQL> --
SQL>
SQL> --
SQL> -- Set a variable to reuse the returned
SQL> -- max value
SQL> --
SQL> --
SQL> -- Rather dumb idea as the max() from
SQL> -- any query will miss any new values
SQL> -- inserted by other sessions and not
SQL> -- yet committed
SQL> --
SQL> column maxval new_value next_key
SQL>
SQL> --
SQL> -- Return current max(keycol)
SQL> --
SQL> -- Not reliable in the least
SQL> -- unless there is only one user
SQL> -- ever on the system, and it's
SQL> -- you
SQL> --
SQL> select max(keycol) maxval from ins_test;

    MAXVAL
----------
         6

SQL>
SQL> --
SQL> -- Use the saved value for the next insert
SQL> --
SQL> -- Not a good idea
SQL> --
SQL> -- Using a sequence and a trigger is far
SQL> -- more reliable and recommended
SQL> --
SQL> insert into ins_test (keycol, keyval)
  2  values (&next_key + 1, 'Next value in line');
old   2: values (&next_key + 1, 'Next value in line')
new   2: values (         6 + 1, 'Next value in line')
insert into ins_test (keycol, keyval)
*
ERROR at line 1:
ORA-00001: unique constraint (BING.INS_TEST_PK) violated


SQL>
SQL> --
SQL> -- Wait for a minute so a second insert of this
SQL> -- same type can occur from a different session
SQL> --
SQL>
SQL> exec dbms_lock.sleep(60);

PL/SQL procedure successfully completed.

Revisiting Session 1 we see the commit has taken place and the changes enacted have been saved:

SQL>
SQL> --
SQL> -- Commit the changes, or try to
SQL> --
SQL> commit;

Commit complete.

SQL>

In Session 2 we also issue a commit, but as we saw earlier there are no changes to save:

SQL>
SQL> --
SQL> -- Commit the changes, or try to
SQL> --
SQL> commit;

Commit complete.

SQL>

And this sort of occurrence can continue because the application was written absent the knowledge of how Oracle constructs its read-consistent images.

Is there a solution? Yes, and it’s a solution Oracle has had available for many years: use a sequence. Let’s now look at how this same set of events change when using a sequence and a trigger to generate the key value for an insert. Again, we start from Session 1:

SQL> --
SQL> -- Create test table
SQL> --
SQL> create table ins_test(keycol number, keyval varchar2(20));

Table created.

SQL>
SQL> --
SQL> -- Add primary key constraint
SQL> --
SQL> alter table ins_test add constraint ins_test_pk primary key (keycol);

Table altered.

SQL>
SQL> --
SQL> -- Add a sequence, and a trigger, to populate the key column
SQL> --
SQL> create sequence ins_test_seq
  2  start with 1
  3  increment by 1
  4  nomaxvalue
  5  nocycle
  6  order;

Sequence created.

SQL>
SQL> create or replace trigger pop_ins_test_pk
  2  before insert on ins_test
  3  for each row
  4  begin
  5        select ins_test_seq.nextval
  6        into :new.keycol
  7        from dual;
  8  end;
  9  /

Trigger created.

SQL>
SQL> --
SQL> -- Insert data
SQL> --
SQL> insert all
  2  into ins_test
  3  (keyval)
  4  values
  5  ('First value')
  6  into ins_test
  7  (keyval)
  8  values
  9  ('Second value')
 10  into ins_test
 11  (keyval)
 12  values
 13  ('Third value')
 14  into ins_test
 15  (keyval)
 16  values
 17  ('Fourth value')
 18  into ins_test
 19  (keyval)
 20  values
 21  ('Fifth value')
 22  into ins_test
 23  (keyval)
 24  values
 25  ('Sixth value')
 26  select * from dual;

6 rows created.

SQL>
SQL> --
SQL> -- Commit changes
SQL> --
SQL> commit;

Commit complete.

SQL>
SQL> insert into ins_test (keyval)
  2  values ('Next value in line');

1 row created.

SQL>
SQL> --
SQL> -- Wait for a minute so a second insert of this
SQL> -- same type can occur from a different session
SQL> --
SQL>
SQL> exec dbms_lock.sleep(60);

PL/SQL procedure successfully completed.

SQL>

Now we visit Session 2 and try our insert:

SQL> --
SQL> -- Using a sequence and a trigger is far
SQL> -- more reliable and recommended
SQL> --
SQL> insert into ins_test (keyval)
  2  values ('Next value in line');

1 row created.

SQL>
SQL> --
SQL> -- Wait for a minute so a second insert of this
SQL> -- same type can occur from a different session
SQL> --
SQL>
SQL> exec dbms_lock.sleep(60);

PL/SQL procedure successfully completed.

SQL>

Allowing both sessions to commit their changes and querying the table from both we see: Session 1 —

SQL> --
SQL> -- Commit the changes, or try to
SQL> --
SQL> commit;

Commit complete.

SQL>
SQL> select * from ins_test;

    KEYCOL KEYVAL    
---------- --------------------
         1 First value
         2 Second value
         3 Third value
         4 Fourth value
         5 Fifth value
         6 Sixth value
         7 Next value in line

7 rows selected.

SQL>

Session 2 —

SQL> --
SQL> -- Commit the changes, or try to
SQL> --
SQL> commit;

Commit complete.

SQL>
SQL> select * from ins_test;

    KEYCOL KEYVAL     
---------- --------------------
         8 Next value in line
         1 First value
         2 Second value
         3 Third value
         4 Fourth value
         5 Fifth value
         6 Sixth value
         7 Next value in line

8 rows selected.

SQL>

Notice no ORA-00001 error was generated, since a sequence doesn’t rely upon existing table values to generate the next number in line. And also notice that the trigger allowed the users to avoid having to enter the key value as it was generated and populated from the trigger by a call to the relevant sequence. AND all users get to call the same trigger so everyone gets the same treatment because each call to NEXTVAL generates a unique value, regardless of which session originates the request.

So, now we know that Oracle won’t let any session outside of the one creating data changes ‘see’ what has yet to be committed. And, knowing that, it should be fairly obvious that a ‘select max()’ query is useless in generating sequential key values in a multi-user system. This is exactly why Oracle provides sequences, to allow multiple users to insert data into the same table at essentially the same time without generating any constraint violation errors. Thus, using a sequence and a trigger is the accepted and expected method for generating numeric key values.

Using a trigger is not the only way to utilize a sequence as the sequence can be used directly in a VALUES clause of an INSERT statement, and since one can access either the next value or the current value of a sequence it’s fairly easy to populate more than one column with the exact same value:

SQL> create sequence myseq
  2  start with 1 increment by 1 nomaxvalue nocycle nocache;

Sequence created.

SQL> create table seqtest(myval number, myotherval number);

Table created.

SQL> insert into seqtest
  2  values (myseq.nextval, myseq.currval)
  3  /

1 row created.

SQL> select * from seqtest;

     MYVAL MYOTHERVAL
---------- ----------
         1          1

SQL>

The first call to a sequence in a session must be to the NEXTVAL operator as a call to CURRVAL will fail:

SQL> select myseq.currval from dual;
select myseq.currval from dual
       *
ERROR at line 1:
ORA-08002: sequence MYSEQ.CURRVAL is not yet defined in this session


SQL>

After the first call to NEXTVAL for a given sequence has been made, however, you can call CURRVAL for that same sequence as often as you wish:

SQL> select myseq.nextval from dual;

   NEXTVAL
----------
         2

SQL> select myseq.currval from dual;

   CURRVAL
----------
         2

SQL> select myseq.currval from dual;

   CURRVAL
----------
         2

SQL> select myseq.currval from dual;

   CURRVAL
----------
         2

SQL> select myseq.currval from dual;

   CURRVAL
----------
         2

SQL> select myseq.currval from dual;

   CURRVAL
----------
         2

SQL> select myseq.currval from dual;

   CURRVAL
----------
         2

SQL>

As you can see it’s possible to populate any number of columns with the same value once CURRVAL for the given sequence has been defined. CURRVAL is assigned the value from the most recent NEXTVAL call; it’s a way to preserve the currently generated sequence value so you can use it multiple times. Trying to find the current and next value of a sequence CANNOT be done using the NEXTVAL and CURRVAL calls as CURRVAL will ALWAYS be equal to the value generated by NEXTVAL. Use the query posted toward the bottom of this post to see where your sequence values are currently and what the next generated value will be. And, if this is the desired behaviour for every insert the trigger code listed above can be modified to populate multiple columns at the same time with the exact same sequence number. Pretty slick, I’d say.

And you can create a sequence starting with the next available value in a column:

SQL> column nxt new_value snum
SQL>
SQL> select max(empno)+1 nxt from emp;

       NXT
----------
      7935

SQL>
SQL> create sequence emp_seq
  2  start with &snum
  3  increment by 1
  4  nomaxvalue
  5  nocycle;
old   2: start with &snum
new   2: start with       7935

Sequence created.

SQL>

This, of course, presumes no one else is trying to add any records to this table, as any uncommitted inserts will not be seen by this process. You could end up with key violations using your brand new sequence because what you thought was the highest value in the table really wasn’t:

SQL> INSERT
  2  INTO EMP VALUES
  3          (7935, 'SMITH',  'CLERK',     7902,
  4          TO_DATE('17-DEC-1999', 'DD-MON-YYYY'),  900, NULL, 20);

1 row created.

SQL>

Creating sequence in the midst of this insert:

SQL> column nxt new_value snum
SQL>
SQL> select max(empno)+1 nxt from emp;

NXT
----------
7935

SQL>
SQL> create sequence emp_seq
2 start with &snum
3 increment by 1
4 nomaxvalue
5 nocycle;
old 2: start with &snum
new 2: start with 7935

Sequence created.

SQL>

Now we commit the prior insert:

SQL> commit;

Commit complete.

SQL>

And we fail on insert in session #2:

SQL> insert into emp
  2  values
  3  (emp_seq.nextval, 'LORPO', 'CLERK', 7902, to_date('27-JUN-2003','DD-MON-YYYY'), 975, null, 20);
insert into emp
*
ERROR at line 1:
ORA-00001: unique constraint (BING.EMP_PK) violated


SQL>

So creating a sequence based upon a maximum column value can be done, but it also can backfire on you. I’d make certain no one is doing any work should you try this.

You can also create a sequence which cycles (or ‘wraps’, but since Oracle provides a wrap utility I’d prefer to not use that terminology for such a sequence):

SQL> create sequence my_cycle_seq
  2  start with 1
  3  increment by 1
  4  cycle
  5  cache 2
  6  maxvalue 5;

Sequence created.

SQL>
SQL> select my_cycle_seq.nextval
  2  from dual;

   NEXTVAL
----------
         1

SQL>
SQL> select my_cycle_seq.nextval
  2  from dual;

   NEXTVAL
----------
         2

SQL>
SQL> select my_cycle_seq.nextval
  2  from dual;

   NEXTVAL
----------
         3

SQL>
SQL> select my_cycle_seq.nextval
  2  from dual;

   NEXTVAL
----------
         4

SQL>
SQL> select my_cycle_seq.nextval
  2  from dual;

   NEXTVAL
----------
         5

SQL>
SQL> select my_cycle_seq.nextval
  2  from dual;

   NEXTVAL
----------
         1

SQL>

Such sequences could be used for printer queues, for example, to provide a fixed number of printer IDs since, as illustrated, they generate values from the minimum to the maximum then start over again at the minimum value. In Oracle the sequence audses$, which sets the sessionid a new session is assigned, is set to cycle and has a rather large maxvalue; in some releases it’s set to 2000000000 so it could be a long time before you’ll see a sessionid value repeat.

Sequence values are returned in the order in which they are requested, regardless of which session is making the sequence call. Caching sequence values can speed things up a bit, since the cache is populated with the number of values specified in the CACHE parameter; if, for example, the cache was set for 20 entries then 20 values, starting with the next available value, would be immediately available, regardless of which session is making the sequence call. If you use all of them it’s faster than generating them ‘on the fly’, but you can, and will, lose sequence values if not all are used and the session terminates; another way to lose sequence values is to rollback a transaction where a sequence was used to populate a value which means that using sequences will NOT produce a gap-less series of sequential numbers so you’ll need to get used to that.  If, on the other hand, you want all of the sequence numbers to fall ‘in order’ regardless of the session generating the value a sequence can be created with the keyword ‘ORDER’. Yes, that’s confusing on the face of it because the sequence values each user ‘sees’ can be in order. The ‘ORDER’ option is to preserve the order of sequence values across nodes in a RAC environment, to more closely coincide with, say, a process date if one is stored in the row. And,yes, you can use both caching and cross-node ordering when creating a sequence:

SQL> create sequence empseq
  2  start with 1 increment by 1 cache 20 order nomaxvalue  nocycle;

Sequence created.

SQL>

but Oracle will let the ORDER option take precendence over caching, which makes sense given that you’ve asked for all of your sequence values to be in order, regardless which RAC node generates them.

A sequence can be created with a MAXVALUE declared and NOCYCLE specified which can create a problem:

SQL> create sequence mynewseq
  2  start with 1 increment by 1 nocycle maxvalue 6 nocache;

Sequence created.

SQL>
SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         1

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         2

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         3

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         4

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         5

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         6

SQL> select mynewseq.nextval from dual;
select mynewseq.nextval from dual
*
ERROR at line 1:
ORA-08004: sequence MYNEWSEQ.NEXTVAL exceeds MAXVALUE and cannot be
instantiated


SQL>

One way to fix this is to alter the sequence to increase the MAXVALUE:

SQL> alter sequence mynewseq maxvalue 10;

Sequence altered.

SQL>
SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         7

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         8

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
         9

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
        10

SQL> select mynewseq.nextval from dual;
select mynewseq.nextval from dual
*
ERROR at line 1:
ORA-08004: sequence MYNEWSEQ.NEXTVAL exceeds MAXVALUE and cannot be
instantiated


SQL>

Obviously the MAXVALUE wasn’t adjusted enough; the process can be repeated ad infinitum/ad nauseum every time the above error is received. Or the sequence can be altered in this manner, which corrects the problem:

SQL> alter sequence mynewseq nomaxvalue;

Sequence altered.

SQL>
SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
        21

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
        22

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
        23

SQL> select mynewseq.nextval from dual;

   NEXTVAL
----------
        24

SQL>

Now the sequence will generate values forever, producing no ugly ORA-08004 errors.

Tracking your sequence values is an easy task, as a simple query of USER_SEQUENCES will prove:

SQL> SELECT sequence_name, last_number curr_val, increment_by,
  2  last_number + Increment_by next_val
  3  FROM user_sequences;

SEQUENCE_NAME                    CURR_VAL INCREMENT_BY   NEXT_VAL
------------------------------ ---------- ------------ ----------
UGROUP_SEQUENCE                         1            1          2
OBJECT_GRANT                       579936            1     579937
SYSTEM_GRANT                        60949            1      60950
PROFNUM$                                1            1          2
AUDSES$                          18184437            1   18184438
SNAPSHOT_ID$                            1            1          2
SNAPSITE_ID$                            1            1          2
JOBSEQ                                  1            1          2
RGROUPSEQ                               1            1          2
ORA_TQ_BASE$                       308209            1     308210
PARTITION_NAME$                     12861            1      12862

SEQUENCE_NAME                    CURR_VAL INCREMENT_BY   NEXT_VAL
------------------------------ ---------- ------------ ----------
CDC_SUBSCRIBE_SEQ$                      1            1          2
CDC_RSID_SEQ$                           1            1          2
LOG$SEQUENCE                            1            1          2
PSINDEX_SEQ$                          100            1        101
AWSEQ$                               1000            1       1001
STREAMS$_CAPTURE_INST                   1            1          2
APPLY$_SOURCE_OBJ_ID                    1            1          2
APPLY$_DEST_OBJ_ID                      1            1          2
APPLY$_ERROR_HANDLER_SEQUENCE           1            1          2
IDGEN1$                           9509051           50    9509101
AQ$_TRANS_SEQUENCE                     21            1         22

SEQUENCE_NAME                    CURR_VAL INCREMENT_BY   NEXT_VAL
------------------------------ ---------- ------------ ----------
AQ$_PROPAGATION_SEQUENCE                1            1          2
AQ$_CHAINSEQ                            1            1          2
AQ$_IOTENQTXID                          1            1          2
AQ$_RULE_SET_SEQUENCE                   1            1          2
AQ$_RULE_SEQUENCE                       1            1          2
AQ$_PUBLISHER_SEQUENCE                  1            1          2
GENERATOR$_S                            1            1          2
STREAMS$_RULE_NAME_S                    1            1          2
HS$_FDS_CLASS_S                        21            1         22
HS$_FDS_INST_S                          1            1          2
HS$_CLASS_CAPS_S                        1            1          2

SEQUENCE_NAME                    CURR_VAL INCREMENT_BY   NEXT_VAL
------------------------------ ---------- ------------ ----------
HS$_INST_CAPS_S                         1            1          2
HS$_BASE_DD_S                         121            1        122
HS$_CLASS_DD_S                          1            1          2
HS$_INST_DD_S                           1            1          2
HS$_CLASS_INIT_S                        1            1          2
HS$_INST_INIT_S                         1            1          2
JAVA$POLICY$SEQUENCE$                  91            1         92
INVALIDATION_REG_ID$                    1            1          2
WRI$_ADV_SEQ_TASK                   17608            1      17609
WRI$_ADV_SEQ_DIR                        1            1          2
WRI$_ADV_SEQ_JOURNAL                    1            1          2

SEQUENCE_NAME                    CURR_VAL INCREMENT_BY   NEXT_VAL
------------------------------ ---------- ------------ ----------
WRI$_ADV_SEQ_MSGGROUP              131551            1     131552
WRI$_ADV_SEQ_SQLW_QUERY                 1            1          2
DBMS_LOCK_ID                   1073741824            1 1073741825
AQ$_SCHEDULER$_JOBQTAB_N               21            1         22
SCHEDULER$_INSTANCE_S               11357            1      11358
SCHEDULER$_EVTSEQ                       1            1          2
AQ$_SCHEDULER$_EVENT_QTAB_N             1            1          2
SCHEDULER$_OLDOIDS_S                    1            1          2
SCHEDULER$_JOBSUFFIX_S                  1            1          2
STREAMS$_APPLY_SPILL_TXNKEY_S           1            1          2
FGR$_NAMES_S                            1            1          2

SEQUENCE_NAME                    CURR_VAL INCREMENT_BY   NEXT_VAL
------------------------------ ---------- ------------ ----------
AQ$_KUPC$DATAPUMP_QUETAB_N              1            1          2
IDX_RB$JOBSEQ                           1            1          2
ORA_PLAN_ID_SEQ$                       11            1         12
MV_RF$JOBSEQ                            1            1          2
AQ$_AQ$_MEM_MC_N                       21            1         22
WRI$_ALERT_SEQUENCE                   303            1        304
AQ$_ALERT_QT_N                         41            1         42
WRI$_ALERT_THRSLOG_SEQUENCE             1            1          2
WRI$_SQLSET_ID_SEQ                      1            1          2
WRI$_SQLSET_REF_ID_SEQ                  1            1          2
WRI$_SQLSET_STMT_ID_SEQ                 1            1          2

SEQUENCE_NAME                    CURR_VAL INCREMENT_BY   NEXT_VAL
------------------------------ ---------- ------------ ----------
WRR$_CAPTURE_ID                         1            1          2
AQ$_SYS$SERVICE_METRICS_TAB_N          21            1         22
JAVA$PREFS$SEQ$                        21            1         22
REDEF_SEQ$                              1            1          2
CACHE_STATS_SEQ_1                       1            1          2
CACHE_STATS_SEQ_0                       1            1          2
TSM_MIG_SEQ$                            1            1          2
UTL_RECOMP_SEQ                          1            1          2

74 rows selected.

SQL>

Using sequences is the most reliable way to populate sequentially numbered columns, as the sequence values are generated on a per-session basis and no two sessions can have duplicate sequence numbers. It makes for less coding later and more reliable (and scalable) inserts in the long run.

Sequences. They can be good for what ‘ails’ you.

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: