~raginggoblin/infolog/infolog

« back to all changes in this revision

Viewing changes to InfologServer/lib/hibernate-distribution-3.3.2.GA/project/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java

  • Committer: Raging Goblin
  • Date: 2013-11-16 16:51:32 UTC
  • Revision ID: raging_goblin-20131116165132-weujnptzc88uy4ah
Mavenized the project, now using shared project InfologSync

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Hibernate, Relational Persistence for Idiomatic Java
3
 
 *
4
 
 * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
5
 
 * indicated by the @author tags or express copyright attribution
6
 
 * statements applied by the authors.  All third-party contributions are
7
 
 * distributed under license by Red Hat Middleware LLC.
8
 
 *
9
 
 * This copyrighted material is made available to anyone wishing to use, modify,
10
 
 * copy, or redistribute it subject to the terms and conditions of the GNU
11
 
 * Lesser General Public License, as published by the Free Software Foundation.
12
 
 *
13
 
 * This program is distributed in the hope that it will be useful,
14
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15
 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
16
 
 * for more details.
17
 
 *
18
 
 * You should have received a copy of the GNU Lesser General Public License
19
 
 * along with this distribution; if not, write to:
20
 
 * Free Software Foundation, Inc.
21
 
 * 51 Franklin Street, Fifth Floor
22
 
 * Boston, MA  02110-1301  USA
23
 
 *
24
 
 */
25
 
package org.hibernate.dialect.lock;
26
 
 
27
 
import org.hibernate.persister.entity.Lockable;
28
 
import org.hibernate.LockMode;
29
 
import org.hibernate.HibernateException;
30
 
import org.hibernate.StaleObjectStateException;
31
 
import org.hibernate.JDBCException;
32
 
import org.hibernate.pretty.MessageHelper;
33
 
import org.hibernate.exception.JDBCExceptionHelper;
34
 
import org.hibernate.sql.Update;
35
 
import org.hibernate.engine.SessionImplementor;
36
 
import org.hibernate.engine.SessionFactoryImplementor;
37
 
import org.slf4j.Logger;
38
 
import org.slf4j.LoggerFactory;
39
 
 
40
 
import java.io.Serializable;
41
 
import java.sql.PreparedStatement;
42
 
import java.sql.SQLException;
43
 
 
44
 
/**
45
 
 * A locking strategy where the locks are obtained through update statements.
46
 
 * <p/>
47
 
 * This strategy is not valid for read style locks.
48
 
 *
49
 
 * @since 3.2
50
 
 *
51
 
 * @author Steve Ebersole
52
 
 */
53
 
public class UpdateLockingStrategy implements LockingStrategy {
54
 
        private static final Logger log = LoggerFactory.getLogger( UpdateLockingStrategy.class );
55
 
 
56
 
        private final Lockable lockable;
57
 
        private final LockMode lockMode;
58
 
        private final String sql;
59
 
 
60
 
        /**
61
 
         * Construct a locking strategy based on SQL UPDATE statements.
62
 
         *
63
 
         * @param lockable The metadata for the entity to be locked.
64
 
         * @param lockMode Indictates the type of lock to be acquired.  Note that
65
 
         * read-locks are not valid for this strategy.
66
 
         */
67
 
        public UpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
68
 
                this.lockable = lockable;
69
 
                this.lockMode = lockMode;
70
 
                if ( lockMode.lessThan( LockMode.UPGRADE ) ) {
71
 
                        throw new HibernateException( "[" + lockMode + "] not valid for update statement" );
72
 
                }
73
 
                if ( !lockable.isVersioned() ) {
74
 
                        log.warn( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
75
 
                        this.sql = null;
76
 
                }
77
 
                else {
78
 
                        this.sql = generateLockString();
79
 
                }
80
 
        }
81
 
 
82
 
        /**
83
 
         * @see LockingStrategy#lock
84
 
         */
85
 
        public void lock(
86
 
                        Serializable id,
87
 
                Object version,
88
 
                Object object,
89
 
                SessionImplementor session) throws StaleObjectStateException, JDBCException {
90
 
                if ( !lockable.isVersioned() ) {
91
 
                        throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
92
 
                }
93
 
                // todo : should we additionally check the current isolation mode explicitly?
94
 
                SessionFactoryImplementor factory = session.getFactory();
95
 
                try {
96
 
                        PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
97
 
                        try {
98
 
                                lockable.getVersionType().nullSafeSet( st, version, 1, session );
99
 
                                int offset = 2;
100
 
 
101
 
                                lockable.getIdentifierType().nullSafeSet( st, id, offset, session );
102
 
                                offset += lockable.getIdentifierType().getColumnSpan( factory );
103
 
 
104
 
                                if ( lockable.isVersioned() ) {
105
 
                                        lockable.getVersionType().nullSafeSet( st, version, offset, session );
106
 
                                }
107
 
 
108
 
                                int affected = st.executeUpdate();
109
 
                                if ( affected < 0 ) {
110
 
                                        factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
111
 
                                        throw new StaleObjectStateException( lockable.getEntityName(), id );
112
 
                                }
113
 
 
114
 
                        }
115
 
                        finally {
116
 
                                session.getBatcher().closeStatement( st );
117
 
                        }
118
 
 
119
 
                }
120
 
                catch ( SQLException sqle ) {
121
 
                        throw JDBCExceptionHelper.convert(
122
 
                                        session.getFactory().getSQLExceptionConverter(),
123
 
                                sqle,
124
 
                                "could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
125
 
                                sql
126
 
                        );
127
 
                }
128
 
        }
129
 
 
130
 
        protected String generateLockString() {
131
 
                SessionFactoryImplementor factory = lockable.getFactory();
132
 
                Update update = new Update( factory.getDialect() );
133
 
                update.setTableName( lockable.getRootTableName() );
134
 
                update.setPrimaryKeyColumnNames( lockable.getRootTableIdentifierColumnNames() );
135
 
                update.setVersionColumnName( lockable.getVersionColumnName() );
136
 
                update.addColumn( lockable.getVersionColumnName() );
137
 
                if ( factory.getSettings().isCommentsEnabled() ) {
138
 
                        update.setComment( lockMode + " lock " + lockable.getEntityName() );
139
 
                }
140
 
                return update.toStatementString();
141
 
        }
142
 
 
143
 
        protected LockMode getLockMode() {
144
 
                return lockMode;
145
 
        }
146
 
}