重点
我们通常说的事务对象,就是这里的 DataSourceTransactionObject。
说起事务,必然是和连接绑定的,DataSourceTransactionObject 主要是管理连接对象。
doGetTransaction() 主要做了:
- 创建一个事务对象 DataSourceTransactionObject
- 拿到数据源,根据当前线程拿到从该数据源拿到的连接对象 ConnectionHolder。
- 设置事务对象的初始值,连接为 ConnectionHolder,状态 newTransaction 为 false,表示不是新连接。
注意:如果是最外层的事务(新连接),这里的初始值 ,就不能代表真实情况(ConnectionHolder 为 null,false 应该为 true)。4.1.1 后面的代码回去改变这个值。
类 AbstractPlatformTransactionManager
@Override
protected Object doGetTransaction() {
//这就是事务对象
//管理connection对象(ConnectionHolder),创建回滚点,按照回滚点回滚,释放回滚点
DataSourceTransactionObject txObject = new DataSourceTransactionObject();
//DataSourceTransactionManager默认是允许嵌套事务的
txObject.setSavepointAllowed(isNestedTransactionAllowed());
//obtainDataSource() 获取数据源对象(自己设置的),其实就是数据库连接池
//这一步是为了拿到外层事务的连接。如果这是最外层事务,就拿不到,为null。
conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
//设置初始值,这里可以理解为假设拿到了conHolder,那么状态就是false,不是新连接
//4.1.1后面的步骤会更改这个值
txObject.setConnectionHolder(conHolder, false);
return txObject;
}
跟 getResource:
类 TransactionSynchronizationManager
@Nullable
//数据源对象
public static Object getResource(Object key) {
//看看数据源连接池有没有扩展,一般没有
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Object value = doGetResource(actualKey);
if (value != null && logger.isTraceEnabled()) {
logger.trace("Retrieved value [" + value + "] for key [" + actualKey + "] bound to thread [" +
Thread.currentThread().getName() + "]");
}
return value;
}
跟 doGetResource:
@Nullable
private static Object doGetResource(Object actualKey) {
//拿到和当前线程绑定的<数据源,连接>
Map<Object, Object> map = resources.get();
if (map == null) {
return null;
}
//获取连接
Object value = map.get(actualKey);
// Transparently remove ResourceHolder that was marked as void...
//不看
if (value instanceof ResourceHolder && ((ResourceHolder) value).isVoid()) {
map.remove(actualKey);
// Remove entire ThreadLocal if empty...
if (map.isEmpty()) {
resources.remove();
}
value = null;
}
return value;
}