12.2 LOB Locators and Transaction Boundaries
LOB locators can be used in both transactions as well as transaction IDs.
See Also:
Locator Interface for LOBs for more information about LOB locators12.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
...FOR
UPDATE
implicitly 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.
-
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
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.
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.
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
SELECT
INTO
(at t1), the value inad_sourcetext
is associated with the locatorclob_updated
. -
The second operation (at t2), uses the
DBMS_LOB
.WRITE
function to alter the value inclob_updated
, and aDBMS_LOB
.READ
reveals a new value. -
The
commit
statement (at t3) ends the current transaction. -
Therefore (at t4), the subsequent
DBMS_LOB
.WRITE
operation fails because theclob_updated
locator 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.
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; /