- 一个事务同一时刻只能占有一个数据库链接
- 一个数据库链接可以被多个事务使用,取决于数据库的连接池
- 数据库连接池中空闲链接超时,回收。
- 一个事务执行时间超过了数据库连接池的最大
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
......
Session session = null;
try {
// 判断当前事务有无Session或者需不需以事务的方式运行
if (txObject.getSessionHolder() == null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Interceptor entityInterceptor = getEntityInterceptor();
// 获取新的事务
Session newSession = (entityInterceptor != null ?
getSessionFactory().withOptions().interceptor(entityInterceptor).openSession() :
getSessionFactory().openSession());
if (logger.isDebugEnabled()) {
logger.debug("Opened new Session [" + newSession + "] for Hibernate transaction");
}
txObject.setSession(newSession);
}
session = txObject.getSessionHolder().getSession();
// 是否提前准备数据库链接并且是否Session一直持有同一个connection
if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
// We're allowed to change the transaction settings of the JDBC Connection.
if (logger.isDebugEnabled()) {
logger.debug("Preparing JDBC Connection of Hibernate Session [" + session + "]");
}
// 获取一个connection,并与当前Session绑定
Connection con = ((SessionImplementor) session).connection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
if (this.allowResultAccessAfterCompletion && !txObject.isNewSession()) {
int currentHoldability = con.getHoldability();
if (currentHoldability != ResultSet.HOLD_CURSORS_OVER_COMMIT) {
txObject.setPreviousHoldability(currentHoldability);
con.setHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT);
}
}
}
.......
// Register the Hibernate Session's JDBC Connection for the DataSource, if set.
if (getDataSource() != null) {
Connection con = ((SessionImplementor) session).connection();
ConnectionHolder conHolder = new ConnectionHolder(con);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
conHolder.setTimeoutInSeconds(timeout);
}
if (logger.isDebugEnabled()) {
logger.debug("Exposing Hibernate transaction as JDBC transaction [" + con + "]");
}
TransactionSynchronizationManager.bindResource(getDataSource(), conHolder);
txObject.setConnectionHolder(conHolder);
}
}
}
在一个事务开始前,对Session以及相关的connection进行了初始化。其中 Connection con = ((SessionImplementor) session).connection();
是通过调用SessionImpl的connection方法完成的绑定数据库链接。
@Override
public Connection connection() throws HibernateException {
errorIfClosed();
return this.jdbcCoordinator.getLogicalConnection().getPhysicalConnection();
}
获得一个具体的真实的物理数据库链接是通过具体的数据库链接提供类完成的。以常见的mysql jdbc为例:
@Override
public Connection getConnection() throws SQLException {
if ( !available ) {
throw new HibernateException( "Provider is closed!" );
}
return useCredentials ? dataSource.getConnection( user, pass ) : dataSource.getConnection();
}