public abstract class TransactionSynchronizationManager {
TransactionSynchronizationManager是管理需要同步的事务资源,也可以管理线程,可以把资源绑定到当前线程当中。
下面介绍一下TransactionSynchronizationManager类的一些关键方法:
public static boolean hasResource(Object key) {
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Object value = doGetResource(actualKey);
return (value != null);
}
上面的方法时判断在当前线程中能不能找到session,
判断当前线程是否已经绑定了session,key是sessionFactory对象,一个sessionFactory可以绑定一个session
TransactionSynchronizationUtils工具类的unwrapResourceIfNecessary()方法是解除包装的方法。当一个包装好了的类丢进去则返回的是原始的类,当传进去是一个没包装的类,返回的还是它自己,也就是传进sessionFactory进去,返回的还是sessionFactory。
public static void bindResource(Object key, Object value) throws IllegalStateException {
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Assert.notNull(value, "Value must not be null");
Map
private static final ThreadLocal
public class ThreadLocal {
public class NamedThreadLocal extends ThreadLocal {
这里ThreadLocal和NamedThreadLocal大概都是一样的,只是
NamedThreadLocal可以通过名字来创建。
我们来到ThreadLocal类里面:
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
t.threadLocals=new ThreadLocalMap(this,firstValue); 这里的this就是这个类本身ThreadLocal
ThreadLocal |
Map |
ThreadLocal |
List |
ThreadLocal |
String |
ThreadLocal |
Boolean |
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);//把类本身传进去当key,得到value(Map,List)
if (e != null)
return (T)e.value;
}
return setInitialValue();
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
所以这里可以看到在上面的
TransactionSynchronizationManager中resouces.get()得到的就是传进去的Map,但是现在的这个Map就是已经绑定到线程里面当中去了的Map,
Object oldValue = map.put(actualKey, value);这里则是把SessionFactory和new new SessionHolder(Session)装进Map里面去了,这里也就绑定到线程里面去了。以上这几段代码就是绑定到线程中。
下面是解绑:
public static Object unbindResource(Object key) throws IllegalStateException {
Object actualKey = TransactionSynchronizationUtils.unwrapResourceIfNecessary(key);
Object value = doUnbindResource(actualKey);
if (value == null) {
throw new IllegalStateException(
"No value for key [" + actualKey + "] bound to thread [" + Thread.currentThread().getName() + "]");
}
return value;
}
unbindResource方法时将该sessionFactory对应的session从线程里面移除,也就是把t.threadLocals这个Map中移除ThreadLocal