14.6. Lock Groups
Prev | Chapter 14. Performance Pack | Next

## 14.6. Lock Groups

The JDO specification provides support for both optimistic and pessimistic transaction types. Typically, optimistic locking is performed at the object level of granularity. That is, concurrent changes in different transactions to any part of a common object will result in an optimistic locking exception being thrown in the transaction that commits last. In many applications, this is acceptable. However, if your application has a high likelihood of concurrent writes to different parts of the same object, then it may be advantageous to use a finer-grained optimistic lock. Additionally, certain parts of an object model may be best modelled without any locking at all, or with a last-commit-wins strategy. It is for these types of situations that Kodo offers customizable optimistic lock groups, which allow you to achieve sub-object-level locking granularity.

For example, an Employee class may have some fields configurable by the employee that the object represents (firstName, lastName, phoneNumber), some that are only modifiable by that employee's manager (salary, title), and some in which concurrent updates are acceptable (a list of projects). In such a model, you can greatly improve the success of concurrent updates in optimistic transactions by putting firstName, lastName, and phoneNumber into one lock group, salary and title into another, and excluding the projects field from optimistic lock checks altogether:

Example 14.22. Lock Group Meta-Data

    public class Employee
    {
        // these fields are configurable by this employee
        private String               firstName;
        private String               lastName;
        private String               phoneNumber;

        // these fields can only be set by the employee's manager
        private float                salary;
        private String               title;

        // this field might be updated concurrently by the employee,
        // other team members, or the employee's manager
        private Set                  projects;
    }

    <?xml version="1.0"?>
    <jdo>
      <package name="">
        <class name="Employee">
          <!-- these fields are implicitly left in the default lock group -->
          <field name="firstName"/>
          <field name="lastName"/>

          <!-- this field is explicitly put into the default lock group -->
          <field name="phoneNumber">
            <extension vendor-name="kodo" key="lock-group" value="default"/>
          </field>

          <!-- these are explicitly put into a non-default lock group -->
          <field name="salary">
            <extension vendor-name="kodo" key="lock-group" value="corporate"/>
          </field>
          <field name="title">
            <extension vendor-name="kodo" key="lock-group" value="corporate"/>
          </field>

          <!-- concurrent updates to this field are ok, so it's
            excluded from locking -->
          <field name="projects">
            <collection element-type="Project"/>
            <extension vendor-name="kodo" key="lock-group" value="none"/>
          </field>
        </class>
      </package>
    </jdo>

Currently, lock groups are only supported when using a relational database, either through a direct connection to the database or through a remote persistence manager. Additionally, lock groups are only currently available when using the `version-number` or `version-date` version indicators (that is, lock groups are not supported by the `state-image` version indicator). Additionally, lock groups should transparently work with any custom extension of `kodo.jdbc.meta.ColumnVersionIndicator`.

### 14.6.1. Lock Group Mapping

When using the custom lock groups with a relational database, Kodo will need a lock column for each of the groups, instead of just one lock column. (Of course, no lock column will be needed for the special `none` group.) Kodo currently requires that all the lock columns for a given object be in the same table. Additionally, it is only possible to use a single version indicator strategy for a given object. That is, you cannot have one numeric lock column and another date lock column.

Example 14.23. Using Lock Groups with version-number Indicator

For the example presented above, corresponding mapping information might look like so. Note that the lock group name is prepended to the attribute name / extension value when specifying the column name for use by non-default lock groups.

    Schema:

    <table name="EMPLOYEE">
        ... primary key columns         ...
        <column name="VERSION1" type="bigint"/>
        <column name="VERSION2" type="bigint"/>
        ... columns for magazine fields ...
    </table>

    Mapping information using the mapping XML format:

    <class name="Employee">
        ... class mapping  ...
        <jdbc-version-ind type="version-number" column="VERSION1"
            corporate-column="VERSION2"/>
        ... field mappings ...
    </class>

    Mapping information using JDO metadata extensions:

    <class name="Employee">
        ... class extensions ...
        <extension vendor-name="kodo" key="jdbc-version-ind" value="version-number">
            <extension vendor-name="kodo" key="column" value="VERSION1"/>
            <extension vendor-name="kodo" key="corporate-column" value="VERSION2"/>
        </extension>
        ... field metadata   ...
    </class>

Prev | Up | Next
14.5. Fetch Groups | Home | 14.7. Profiling