Document 5.2.1 follow-on-locking changes

This commit is contained in:
Vlad Mihalcea 2016-06-23 17:48:26 +03:00
parent 9ac93156a0
commit de584076ec
3 changed files with 48 additions and 2 deletions

View File

@ -234,3 +234,28 @@ include::{extrasdir}/locking-follow-on-secondary-query-example.sql[]
====
The lock request was moved from the original query to a secondary one which takes the previously fetched entities to lock their associated database records.
Prior to Hibernate 5.2.1, the the follow-on-locking mechanism was applied uniformly to any locking query executing on Oracle.
Since 5.2.1, the Oracle Dialect tries to figure out if the current query demand the follow-on-locking mechanism.
Even more important is that you can overrule the default follow-on-locking detection logic and explicitly enable or disable it on a per query basis.
[[locking-follow-on-explicit-example]]
.Disabling the follow-on-locking mechanism explicitly
====
[source, JAVA, indent=0]
----
include::{sourcedir}/ExplicitLockingTest.java[tags=locking-follow-on-explicit-example]
----
[source, SQL, indent=0]
----
include::{extrasdir}/locking-follow-on-explicit-example.sql[]
----
====
[NOTE]
====
The follow-on-locking mechanism should be explicitly enabled only if the current executing query fails because the `FOR UPDATE` clause cannot be applied, meaning that the Dialect resolving mechanism needs to be further improved.
====

View File

@ -0,0 +1,7 @@
SELECT *
FROM (
SELECT p.id as id1_0_, p."name" as name2_0_
FROM Person p
)
WHERE rownum <= 10
FOR UPDATE

View File

@ -25,6 +25,7 @@ import org.hibernate.LockOptions;
import org.hibernate.Session;
import org.hibernate.dialect.Oracle8iDialect;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.query.Query;
import org.hibernate.testing.RequiresDialect;
import org.junit.Test;
@ -96,7 +97,7 @@ public class ExplicitLockingTest extends BaseEntityManagerFunctionalTestCase {
@Test
public void testBuildLockRequest() {
doInJPA( this::entityManagerFactory, entityManager -> {
log.info( "testBuildlLockRequest" );
log.info( "testBuildLockRequest" );
Person person = new Person( "John Doe" );
Phone home = new Phone( "123-456-7890" );
Phone office = new Phone( "098-765-4321" );
@ -138,7 +139,7 @@ public class ExplicitLockingTest extends BaseEntityManagerFunctionalTestCase {
@RequiresDialect(Oracle8iDialect.class)
public void testFollowOnLocking() {
doInJPA( this::entityManagerFactory, entityManager -> {
log.info( "testBuildlLockRequest" );
log.info( "testBuildLockRequest" );
Person person1 = new Person( "John Doe" );
Person person2 = new Person( "Mrs. John Doe" );
@ -169,6 +170,19 @@ public class ExplicitLockingTest extends BaseEntityManagerFunctionalTestCase {
.getResultList();
//end::locking-follow-on-secondary-query-example[]
} );
doInJPA( this::entityManagerFactory, entityManager -> {
//tag::locking-follow-on-explicit-example[]
List<Person> persons = entityManager.createQuery(
"select p from Person p", Person.class)
.setMaxResults( 10 )
.unwrap( Query.class )
.setLockOptions(
new LockOptions( LockMode.PESSIMISTIC_WRITE )
.setFollowOnLocking( false ) )
.getResultList();
//end::locking-follow-on-explicit-example[]
} );
}
//tag::locking-jpa-query-hints-scope-entity-example[]