12.2 LOB Locators and Transaction Boundaries
LOB locators can be used in both transactions as well as transaction IDs.
- About LOB Locators and Transaction Boundaries
 Learn about LOB locators and transaction boundaries in this section.
- Read and Write Operations on a LOB Using Locators
 You can always read LOB data using the locator irrespective of whether or not the locator contains a transaction ID. Learn about various aspects of it in this section.
- Selecting the Locator Outside of the Transaction Boundary
 This section has two scenarios that describe techniques for using locators in non-serializable transactions when the locator is selected outside of a transaction.
- Selecting the Locator Within a Transaction Boundary
 This section has two scenarios that describe techniques for using locators in non-serializable transactions when the locator is selected within a transaction.
- LOB Locators Cannot Span Transactions
 LOB locators that are used to write data cannot span transactions. However, the locator can be used to read the LOB value unless you are in a serializable transaction.
- Example of Locator Not Spanning a Transaction
 The example of locator not spanning a transaction uses theprint_mediatable.
See Also:
Locator Interface for LOBs for more information about LOB locatorsParent topic: Advanced Design Considerations
12.2.1 About LOB Locators and Transaction Boundaries
Learn about LOB locators and transaction boundaries in this section.
Note the following regarding LOB locators and transactions:
- 
                        Locators contain transaction IDs when: You Begin the Transaction, Then Select Locator: If you begin a transaction and subsequently select a locator, then the locator contains the transaction ID. Note that you can implicitly be in a transaction without explicitly beginning one. For example, SELECT...FORUPDATEimplicitly begins a transaction. In such a case, the locator contains a transaction ID.
- 
                        Locators Do Not Contain Transaction IDs When... - 
                              You are Outside the Transaction, Then Select Locator: By contrast, if you select a locator outside of a transaction, then the locator does not contain a transaction ID. 
- 
                              When Selected Prior to DML Statement Execution: A transaction ID is not assigned until the first DML statement executes. Therefore, locators that are selected prior to such a DML statement do not contain a transaction ID. 
 
- 
                              
Parent topic: LOB Locators and Transaction Boundaries
12.2.2 Read and Write Operations on a LOB Using Locators
You can always read LOB data using the locator irrespective of whether or not the locator contains a transaction ID. Learn about various aspects of it in this section.
- 
                        Cannot Write Using Locator: If the locator contains a transaction ID, then you cannot write to the LOB outside of that particular transaction. 
- 
                        Can Write Using Locator: If the locator does not contain a transaction ID, then you can write to the LOB after beginning a transaction either explicitly or implicitly. 
- 
                        Cannot Read or Write Using Locator With Serializable Transactions: If the locator contains a transaction ID of an older transaction, and the current transaction is serializable, then you cannot read or write using that locator. 
- 
                        Can Read, Not Write Using Locator With Non-Serializable Transactions: If the transaction is non-serializable, then you can read, but not write outside of that transaction. 
The examples Selecting the Locator Outside of the Transaction Boundary, Selecting the Locator Within a Transaction Boundary, LOB Locators Cannot Span Transactions, and Example of Locator Not Spanning a Transaction show the relationship between locators and non-serializable transactions
Parent topic: LOB Locators and Transaction Boundaries
12.2.3 Selecting the Locator Outside of the Transaction Boundary
This section has two scenarios that describe techniques for using locators in non-serializable transactions when the locator is selected outside of a transaction.
First Scenario:
- 
                           Select the locator with no current transaction. At this point, the locator does not contain a transaction id. 
- 
                           Begin the transaction. 
- 
                           Use the locator to read data from the LOB. 
- 
                           Commit or rollback the transaction. 
- 
                           Use the locator to read data from the LOB. 
- 
                           Begin a transaction. The locator does not contain a transaction id. 
- 
                           Use the locator to write data to the LOB. This operation is valid because the locator did not contain a transaction id prior to the write. After this call, the locator contains a transaction id. 
Second Scenario:
- Select the locator with no current transaction. At this point, the locator does not contain a transaction id.
- Begin the transaction. The locator does not contain a transaction id.
- Use the locator to read data from the LOB. The locator does not contain a transaction id.
- Use the locator to write data to the LOB. This operation is valid because the locator did not contain a transaction id prior to the write. After this call, the locator contains a transaction id. You can continue to read from or write to the LOB.
- Commit or rollback the transaction. The locator continues to contain the transaction id.
- Use the locator to read data from the LOB. This is a valid operation.
- Begin a transaction. The locator contains the previous transaction id.
- Use the locator to write data to the LOB. This write operation fails because the locator does not contain the transaction id that matches the current transaction.
Parent topic: LOB Locators and Transaction Boundaries
12.2.4 Selecting the Locator Within a Transaction Boundary
This section has two scenarios that describe techniques for using locators in non-serializable transactions when the locator is selected within a transaction.
First Scenario:
- 
                           Select the locator within a transaction. At this point, the locator contains the transaction id. 
- 
                           Begin the transaction. The locator contains the previous transaction id. 
- 
                           Use the locator to read data from the LOB. This operation is valid even though the transaction id in the locator does not match the current transaction. See Also: "Read-Consistent Locators" for more information about using the locator to read LOB data. 
- 
                           Use the locator to write data to the LOB. This operation fails because the transaction id in the locator does not match the current transaction. 
Second Scenario:
- Begin a transaction.
- Select the locator. The locator contains the transaction id because it was selected within a transaction.
- Use the locator to read from or write to the LOB. These operations are valid.
- Commit or rollback the transaction. The locator continues to contain the transaction id.
- Use the locator to read data from the LOB. This operation is valid even though there is a transaction id in the locator and the transaction was previously committed or rolled back.
- Use the locator to write data to the LOB. This operation fails because the transaction id in the locator is for a transaction that was previously committed or rolled back.
Parent topic: LOB Locators and Transaction Boundaries
12.2.5 LOB Locators Cannot Span Transactions
LOB locators that are used to write data cannot span transactions. However, the locator can be used to read the LOB value unless you are in a serializable transaction.
Modifying a persistent LOB value through the LOB locator using DBMS_LOB, OCI, or SQL INSERT or UPDATE statements changes the locator from a read-consistent locator to an updated locator. 
                  
The INSERT or UPDATE statement automatically starts a transaction and locks the row. Once this has occurred, the locator cannot be used outside the current transaction to modify the LOB value. In other words, LOB locators that are used to write data cannot span transactions. However, the locator can be used to read the LOB value unless you are in a serializable transaction.
                  
In the following code example, a CLOB locator called
                clob_updated is created and following operations are performed:
                  
- 
                        At the time of the first SELECTINTO(at t1), the value inad_sourcetextis associated with the locatorclob_updated.
- 
                        The second operation (at t2), uses the DBMS_LOB.WRITEfunction to alter the value inclob_updated, and aDBMS_LOB.READreveals a new value.
- 
                        The commitstatement (at t3) ends the current transaction.
- 
                        Therefore (at t4), the subsequent DBMS_LOB.WRITEoperation fails because theclob_updatedlocator refers to a different (already committed) transaction. This is noted by the error returned. You must re-select the LOB locator before using it in furtherDBMS_LOB(and OCI) modify operations.
Parent topic: LOB Locators and Transaction Boundaries
12.2.6 Example of Locator Not Spanning a Transaction
The example of locator not spanning a transaction uses the print_media
    table.
                  
INSERT INTO PRINT_MEDIA VALUES (2056, 20010, EMPTY_BLOB(), 
    'abcd', EMPTY_CLOB(), EMPTY_CLOB(), NULL, NULL, NULL, NULL);
COMMIT;
DECLARE
  num_var          INTEGER;
  clob_updated     CLOB;
  read_amount      INTEGER;
  read_offset      INTEGER;
  write_amount     INTEGER;
  write_offset     INTEGER;
  buffer           VARCHAR2(20);
BEGIN
          -- At time t1:
     SELECT      ad_sourcetext
     INTO        clob_updated
     FROM        PRINT_MEDIA
     WHERE       ad_id = 20010
     FOR UPDATE;
     read_amount := 10;
     read_offset := 1;
     dbms_lob.read(clob_updated, read_amount, read_offset, buffer);
     dbms_output.put_line('clob_updated value: ' || buffer);
     -- This produces the output 'abcd'
     -- At time t2:
     write_amount := 3;
     write_offset := 5;
     buffer := 'efg';
     dbms_lob.write(clob_updated, write_amount, write_offset, buffer);
     read_amount := 10;
     dbms_lob.read(clob_updated, read_amount, read_offset, buffer);
     dbms_output.put_line('clob_updated value: ' || buffer);
     -- This produces the output 'abcdefg'
    -- At time t3:
    COMMIT;
     -- At time t4:
    dbms_lob.write(clob_updated , write_amount, write_offset, buffer);
    -- ERROR: ORA-22990: LOB locators cannot span transactions
END;
/Parent topic: LOB Locators and Transaction Boundaries