Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/hibernate/dialect/lock/SelectLockingStrategy.java


1   package org.hibernate.dialect.lock;
2   
3   import org.hibernate.persister.entity.Lockable;
4   import org.hibernate.engine.SessionImplementor;
5   import org.hibernate.engine.SessionFactoryImplementor;
6   import org.hibernate.StaleObjectStateException;
7   import org.hibernate.JDBCException;
8   import org.hibernate.LockMode;
9   import org.hibernate.sql.SimpleSelect;
10  import org.hibernate.pretty.MessageHelper;
11  import org.hibernate.exception.JDBCExceptionHelper;
12  
13  import java.io.Serializable;
14  import java.sql.PreparedStatement;
15  import java.sql.ResultSet;
16  import java.sql.SQLException;
17  
18  /**
19   * A locking strategy where the locks are obtained through select statements.
20   * <p/>
21   * For non-read locks, this is achieved through the Dialect's specific
22   * SELECT ... FOR UPDATE syntax.
23   *
24   * @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode)
25   * @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String)
26   * @since 3.2
27   *
28   * @author Steve Ebersole
29   */
30  public class SelectLockingStrategy implements LockingStrategy {
31  
32    private final Lockable lockable;
33    private final LockMode lockMode;
34    private final String sql;
35  
36    /**
37     * Construct a locking strategy based on SQL SELECT statements.
38     *
39     * @param lockable The metadata for the entity to be locked.
40     * @param lockMode Indictates the type of lock to be acquired.
41     */
42    public SelectLockingStrategy(Lockable lockable, LockMode lockMode) {
43      this.lockable = lockable;
44      this.lockMode = lockMode;
45      this.sql = generateLockString();
46    }
47  
48    /**
49     * @see LockingStrategy#lock
50     */
51    public void lock(
52            Serializable id,
53            Object version,
54            Object object,
55            SessionImplementor session) throws StaleObjectStateException, JDBCException {
56  
57      SessionFactoryImplementor factory = session.getFactory();
58      try {
59        PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
60        try {
61          lockable.getIdentifierType().nullSafeSet( st, id, 1, session );
62          if ( lockable.isVersioned() ) {
63            lockable.getVersionType().nullSafeSet(
64                st,
65                version,
66                lockable.getIdentifierType().getColumnSpan( factory ) + 1,
67                session
68            );
69          }
70  
71          ResultSet rs = st.executeQuery();
72          try {
73            if ( !rs.next() ) {
74              if ( factory.getStatistics().isStatisticsEnabled() ) {
75                factory.getStatisticsImplementor()
76                    .optimisticFailure( lockable.getEntityName() );
77              }
78              throw new StaleObjectStateException( lockable.getEntityName(), id );
79            }
80          }
81          finally {
82            rs.close();
83          }
84        }
85        finally {
86          session.getBatcher().closeStatement( st );
87        }
88  
89      }
90      catch ( SQLException sqle ) {
91        throw JDBCExceptionHelper.convert(
92            session.getFactory().getSQLExceptionConverter(),
93            sqle,
94            "could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
95            sql
96          );
97      }
98    }
99  
100   protected LockMode getLockMode() {
101     return lockMode;
102   }
103 
104   protected String generateLockString() {
105     SessionFactoryImplementor factory = lockable.getFactory();
106     SimpleSelect select = new SimpleSelect( factory.getDialect() )
107         .setLockMode( lockMode )
108         .setTableName( lockable.getRootTableName() )
109         .addColumn( lockable.getRootTableIdentifierColumnNames()[0] )
110         .addCondition( lockable.getRootTableIdentifierColumnNames(), "=?" );
111     if ( lockable.isVersioned() ) {
112       select.addCondition( lockable.getVersionColumnName(), "=?" );
113     }
114     if ( factory.getSettings().isCommentsEnabled() ) {
115       select.setComment( lockMode + " lock " + lockable.getEntityName() );
116     }
117     return select.toStatementString();
118   }
119 }