Using schema locks


Summary
The ISchemaLock interface is used to establish an exclusive lock on a dataset when changing its schema or when performing other operations that require exclusive access to the data. The ISchemaLockInfo interface is used in conjunction with ISchemaLock to supply information concerning the schema lock, such as the type of lock and the dataset to which it has been applied.


About schema locks

A schema within the geodatabase is the structure or design of a geodatabase or geodatabase object, such as a table, feature class, or attribute domain as opposed to the underlying data. Schema locks are used to manage geodatabase schemas to ensure the structure of a dataset will not change once it has been opened or referenced. The ISchemaLock interface is used to manage the schema locks associated with a dataset or object.
The following are the schema lock types:
  • Shared schema locks—These are applied automatically by the geodatabase when accessing a dataset and are removed when all references to the dataset are removed. For this reason, it is not necessary to explicitly apply or remove shared schema locks. There is no limit to the number of shared schema locks a dataset or object can have.
  • Exclusive schema locks—In contrast to shared schema locks, exclusive schema locks are controlled by the developer or ArcGIS application, such as ArcMap or ArcCatalog. An exclusive lock is used to lock a geodatabase dataset or object from use by others to make the necessary changes to it. An exclusive lock is promoted from a shared lock and demoted back to a shared lock when no longer needed. The presence of additional shared schema locks on a dataset or object prevents an exclusive schema lock from being applied and precludes the ability to make changes to the underlying dataset and its schema while it is in use. Only one exclusive schema lock is allowed per dataset. As opposed to shared schema locks, exclusive schema locks are not applied or removed automatically. It is the responsibility of the developer to apply or remove exclusive schema locks.

Schema locks with file and ArcSDE geodatabases

File geodatabases are stored as a collection of files in a folder on disk. Users must have read/write access to the folder containing the files that make up the file geodatabase to make changes to its schema.
ArcSDE geodatabases are stored in relational databases, such as Oracle, Microsoft SQL Server, IBM DB2, IBM Informix, or PostgreSQL. These multiuser geodatabases require the use of ArcSDE and can be unlimited in size and number of users. Users must have the appropriate user level permissions to the ArcSDE geodatabase to make changes to its schema.

Schema locks—shared and exclusive—apply to individual datasets or objects, and related tables in a file or ArcSDE geodatabase. For example, see the following:
  • If a lock is acquired on a feature class in a feature dataset, the lock applies to the entire feature dataset and its contents.
  • Locks also apply to both sides of a relationship class. For example, if two stand-alone feature classes are related via a relationship class and an exclusive or shared lock is acquired for one feature class, the lock is also applied to the other feature class in the relationship.
Obtaining an exclusive schema lock on a personal geodatabase invalidates open row sets from the specific personal geodatabase, such as a cursor populated through the IFeatureClass.Search method. For this reason, obtain the exclusive schema lock before populating a row set, such as cursors.

Schema locks with personal geodatabases

Personal geodatabases are stored in a single Microsoft Access database (.mdb) file. Any user that has the proper read/write access to the .mdb file that holds the personal geodatabase can edit and change its schema contents.
Applying schema locks in a personal geodatabase applies a lock to the entire .mdb file. Therefore, while a shared lock might be acquired for a single feature class in a personal geodatabase, this single shared lock prevents exclusive locks from being applied to any other content in the personal geodatabase.

Types of operations requiring exclusive schema locks

Limit the scope of exclusive schema locks to the operation that requires the lock. Gather the necessary information to perform the action, obtain the exclusive lock, make the change, and release the lock. Some examples of operations for which an exclusive schema lock should be obtained include the following:
  • Modifications to attribute domains, such as adding or removing values from a coded value domain or changing the range for range domains
  • Adding or deleting a field from a feature class or object class
  • Associating a class extension with a feature class
  • Creating a topology, geometric network, network dataset, terrain, schematic dataset, representation, or cadastral fabric on a set of feature classes
  • Any use of the IClassSchemaEdit interface
  • Putting a feature class into and taking it out of load-only mode with the IFeatureClassLoad.LoadOnlyMode property
  • Managing (creating, deleting, or modifying) spatial and attribute indexes
Once the action requiring an exclusive schema lock is complete, the exclusive schema lock must be demoted to a shared lock. This includes when errors are raised during the schema modification, for example, consider the case where a field is being deleted from a feature class. To delete the field, an exclusive schema lock is obtained. However, on the call to DeleteField, an error is thrown; that is, the field being deleted is a required field, such as the ObjectID field. In handling the error, demote the exclusive schema lock to a shared lock before proceeding.
The following code example shows how to obtain an exclusive lock. Patterns to note in the code example include the following:
  • Checks for existing exclusive or shared locks are not made before attempting to get an exclusive lock. Instead, the call to establish an exclusive lock (using the ChangeSchemaLock method) is made within a Try block. If an exclusive lock cannot be obtained, an error will be raised and reported to the user.
  • The practice of demoting an exclusive schema lock to a shared lock when an error is raised, or when the lock is no longer required. In the following code example, the exclusive schema lock is demoted in the Finally block, which demotes the exclusive lock at the end of the code execution or when an error is raised.
[C#]
public void DeleteField(IObjectClass objectClass, String fieldName)
{
    // Get the field to be deleted.
    int fieldIndex = objectClass.FindField(fieldName);
    IField field = objectClass.Fields.get_Field(fieldIndex);

    // Cast to the ISchemaLock interface.
    ISchemaLock schemaLock = (ISchemaLock)objectClass;
    try
    {
        // Get an exclusive schema lock on the object class. 
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);

        // Alter the class extension for the class.
        objectClass.DeleteField(field);
    }
    catch (Exception e)
    {
        // An error was raised; therefore, notify the user.
        Console.WriteLine(e.Message);
    }
    finally
    {
        // Since the Finally block is always called, the exclusive lock is demoted
        // to a shared lock after the field is deleted and after an error is raised.
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
    }
}
[VB.NET]
Public Sub DeleteField(ByVal objectClass As IObjectClass, ByVal fieldName As String)
    
    ' Get the field to be deleted.
    Dim fieldIndex As Integer = objectClass.FindField(fieldName)
    Dim field As IField = objectClass.Fields.Field(fieldIndex)
    
    ' Cast to the ISchemaLock interface.
    Dim schemaLock As ISchemaLock = CType(objectClass, ISchemaLock)
    
    Try
    ' Get an exclusive schema lock on the object class.
    schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock)
    
    ' Alter the class extension for the class.
    objectClass.DeleteField(field)
    Catch e As Exception
    ' An error was raised; therefore, notify the user.
    Console.WriteLine(e.Message)
    Finally
    ' Since the Finally block is always called, the exclusive lock is demoted
    ' to a shared lock after the field is deleted and after an error is raised.
    schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock)
    End Try
    
End Sub

Access schema lock information using ISchemaLockInfo

The ISchemaLockInfo interface is used with ISchemaLock to provide information about a schema lock, for example, whether it is shared or exclusive and for ArcSDE geodatabases, the name of the user who has the lock. The following code example shows how to iterate through the set of schema locks for a dataset and determines the user with the schema lock:
[C#]
public void ListSchemaLocksForObjectClass(IObjectClass objectClass)
{
    //Get an exclusive schema lock on the dataset.
    ISchemaLock schemaLock = (ISchemaLock)objectClass;

    // Get an enumerator over the current schema locks.
    IEnumSchemaLockInfo enumSchemaLockInfo = null;
    schemaLock.GetCurrentSchemaLocks(out enumSchemaLockInfo);

    // Iterate through the locks.
    ISchemaLockInfo schemaLockInfo = null;
    while ((schemaLockInfo = enumSchemaLockInfo.Next()) != null)
    {
        Console.WriteLine("{0} : {1} : {2}", schemaLockInfo.TableName,
            schemaLockInfo.UserName, schemaLockInfo.SchemaLockType);
    }
}
[VB.NET]
Public Sub ListSchemaLocksForObjectClass(ByVal objectClass As IObjectClass)
    
    'Get an exclusive schema lock on the dataset.
    Dim schemaLock As ISchemaLock = CType(objectClass, ISchemaLock)
    
    ' Get an enumerator over the current schema locks.
    Dim enumSchemaLockInfo As IEnumSchemaLockInfo = Nothing
    schemaLock.GetCurrentSchemaLocks(enumSchemaLockInfo)
    
    ' Iterate through the locks.
    Dim schemaLockInfo As ISchemaLockInfo = Nothing
    
    Do While Not schemaLockInfo Is Nothing
        Console.WriteLine("{0} : {1} : {2}", schemaLockInfo.TableName, schemaLockInfo.UserName, schemaLockInfo.SchemaLockType)
        schemaLockInfo = enumSchemaLockInfo.Next()
    Loop
    
End Sub






To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Development licensing Deployment licensing
ArcGIS for Desktop Advanced ArcGIS for Desktop Advanced
ArcGIS for Desktop Standard ArcGIS for Desktop Standard
ArcGIS for Desktop Basic ArcGIS for Desktop Basic
Engine Developer Kit Engine: Geodatabase Update