HibernateTransactionManager配单例事务
2015-07-29 22:26
477 查看
HibernateTransactionManager对事务的实现,最终都是通过处理hibernate的Transaction的commit,rollback方法完成,
与单独的hibernate的Transaction事务没有太大的区别;但是,HibernateTransactionManager通过注入sessionfactory.
然后在得到session,把session包装成SessionHolder(),并通过threadlocal来对象的实现和线程的绑定(threadlocal实现重点)
最后到线程中的session取得的Transaction,
[java]
view plaincopyprint?
//SessionHolder对session包装,绑定到threadlocal中去
private final Map<Object, Session> sessionMap = Collections.synchronizedMap(new HashMap<Object, Session>(1));
1.主要理解这个类的 doBegin(),doGetTransaction()方法
[java]
view plaincopyprint?
protected void doBegin(Object transaction, TransactionDefinition definition)
doBegin(Object transaction, TransactionDefinition definition)负责事务的创建
两个参数:
第一个参数:Object transaction
会得到session和一个connection.
设置HibernateTransactionObject,获取线程中的session和connection
[java]
view plaincopyprint?
protected Object doGetTransaction() {
//这是一个SPI类,代表一个SessionHolder
HibernateTransactionObject txObject =
new HibernateTransactionObject();
//在事务中设置保存点,是否允许嵌套事务
txObject.setSavepointAllowed(isNestedTransactionAllowed());
//在绑定的线程中查找当前的session,SessionHolder是session的包装,SessionHolder绑定到threadlocal
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
if (sessionHolder !=
null) {
.......
txObject.setSessionHolder(sessionHolder);
}
else if (this.hibernateManagedSession) {
try {
Session session = getSessionFactory().getCurrentSession();
.......
txObject.setExistingSession(session);
}
catch (HibernateException ex) {
.......
}
}
//得到一个connection,它也是和线程绑定的
if (getDataSource() !=
null) {
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(getDataSource());
txObject.setConnectionHolder(conHolder);
}
return txObject;
}
事务开始的地方
[java]
view plaincopyprint?
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
throw
new IllegalTransactionStateException(
......
Session session = null;
//如果SessionHolder没有被创建,那么这里openSession并放到SessionHolder中去
try {
if (txObject.getSessionHolder() ==
null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Interceptor entityInterceptor = getEntityInterceptor();
Session newSession = (entityInterceptor !=
null ?
getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());
if (logger.isDebugEnabled()) {
......
}
txObject.setSession(newSession);
}
//三种得到session(OpenSessionInView,getcurrentsession,opensession),这里就从SessionHolder得到session
session = txObject.getSessionHolder().getSession();
//设置<tx>isolation,read-only属性
if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
// We're allowed to change the transaction settings of the JDBC Connection.
......
Connection con = session.connection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
}
else {
// Not allowed to change the transaction settings of the JDBC Connection.
......
}
if (definition.isReadOnly() && txObject.isNewSession()) {
// Just set to NEVER in case of a new Session for this transaction.
session.setFlushMode(FlushMode.MANUAL);
}
if (!definition.isReadOnly() && !txObject.isNewSession()) {
// We need AUTO or COMMIT for a non-read-only transaction.
FlushMode flushMode = session.getFlushMode();
if (flushMode.lessThan(FlushMode.COMMIT)) {
session.setFlushMode(FlushMode.AUTO);
txObject.getSessionHolder().setPreviousFlushMode(flushMode);
}
}
Transaction hibTx;
// Register transaction timeout.
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
// Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+
// Applies to all statements, also to inserts, updates and deletes!
hibTx = session.getTransaction();
hibTx.setTimeout(timeout);
hibTx.begin();
}
else {
// Open a plain Hibernate transaction without specified timeout.
//创建并开始事务
hibTx = session.beginTransaction();
}
// Add the Hibernate transaction to the session holder.
//把hibtx事务放到txobject里面,原因是因为这个SessionHolder会和线程绑定
txObject.getSessionHolder().setTransaction(hibTx);
// Register the Hibernate Session's JDBC Connection for the DataSource, if set.
if (getDataSource() !=
null) {
Connection con = 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);
}
// Bind the session holder to the thread.
//如果是新的SessionHolder,把它和线程绑定
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
}
//SessionHolder的状态标识,你的Transaction是一个线程中的session取得的
txObject.getSessionHolder().setSynchronizedWithTransaction(true);
}
catch (Exception ex) {
if (txObject.isNewSession()) {
try {
if (session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
}
catch (Throwable ex2) {
logger.debug("Could not rollback Session after failed transaction begin", ex);
}
finally {
SessionFactoryUtils.closeSession(session);
}
}
throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
}
}
与单独的hibernate的Transaction事务没有太大的区别;但是,HibernateTransactionManager通过注入sessionfactory.
然后在得到session,把session包装成SessionHolder(),并通过threadlocal来对象的实现和线程的绑定(threadlocal实现重点)
最后到线程中的session取得的Transaction,
[java]
view plaincopyprint?
//SessionHolder对session包装,绑定到threadlocal中去
private final Map<Object, Session> sessionMap = Collections.synchronizedMap(new HashMap<Object, Session>(1));
//SessionHolder对session包装,绑定到threadlocal中去 private final Map<Object, Session> sessionMap = Collections.synchronizedMap(new HashMap<Object, Session>(1));
1.主要理解这个类的 doBegin(),doGetTransaction()方法
[java]
view plaincopyprint?
protected void doBegin(Object transaction, TransactionDefinition definition)
protected void doBegin(Object transaction, TransactionDefinition definition)
doBegin(Object transaction, TransactionDefinition definition)负责事务的创建
两个参数:
第一个参数:Object transaction
会得到session和一个connection.
设置HibernateTransactionObject,获取线程中的session和connection
[java]
view plaincopyprint?
protected Object doGetTransaction() {
//这是一个SPI类,代表一个SessionHolder
HibernateTransactionObject txObject =
new HibernateTransactionObject();
//在事务中设置保存点,是否允许嵌套事务
txObject.setSavepointAllowed(isNestedTransactionAllowed());
//在绑定的线程中查找当前的session,SessionHolder是session的包装,SessionHolder绑定到threadlocal
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory());
if (sessionHolder !=
null) {
.......
txObject.setSessionHolder(sessionHolder);
}
else if (this.hibernateManagedSession) {
try {
Session session = getSessionFactory().getCurrentSession();
.......
txObject.setExistingSession(session);
}
catch (HibernateException ex) {
.......
}
}
//得到一个connection,它也是和线程绑定的
if (getDataSource() !=
null) {
ConnectionHolder conHolder = (ConnectionHolder)
TransactionSynchronizationManager.getResource(getDataSource());
txObject.setConnectionHolder(conHolder);
}
return txObject;
}
protected Object doGetTransaction() { //这是一个SPI类,代表一个SessionHolder HibernateTransactionObject txObject = new HibernateTransactionObject(); //在事务中设置保存点,是否允许嵌套事务 txObject.setSavepointAllowed(isNestedTransactionAllowed()); //在绑定的线程中查找当前的session,SessionHolder是session的包装,SessionHolder绑定到threadlocal SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(getSessionFactory()); if (sessionHolder != null) { ....... txObject.setSessionHolder(sessionHolder); } else if (this.hibernateManagedSession) { try { Session session = getSessionFactory().getCurrentSession(); ....... txObject.setExistingSession(session); } catch (HibernateException ex) { ....... } } //得到一个connection,它也是和线程绑定的 if (getDataSource() != null) { ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(getDataSource()); txObject.setConnectionHolder(conHolder); } return txObject; }
事务开始的地方
[java]
view plaincopyprint?
protected void doBegin(Object transaction, TransactionDefinition definition) {
HibernateTransactionObject txObject = (HibernateTransactionObject) transaction;
if (txObject.hasConnectionHolder() && !txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
throw
new IllegalTransactionStateException(
......
Session session = null;
//如果SessionHolder没有被创建,那么这里openSession并放到SessionHolder中去
try {
if (txObject.getSessionHolder() ==
null || txObject.getSessionHolder().isSynchronizedWithTransaction()) {
Interceptor entityInterceptor = getEntityInterceptor();
Session newSession = (entityInterceptor !=
null ?
getSessionFactory().openSession(entityInterceptor) : getSessionFactory().openSession());
if (logger.isDebugEnabled()) {
......
}
txObject.setSession(newSession);
}
//三种得到session(OpenSessionInView,getcurrentsession,opensession),这里就从SessionHolder得到session
session = txObject.getSessionHolder().getSession();
//设置<tx>isolation,read-only属性
if (this.prepareConnection && isSameConnectionForEntireSession(session)) {
// We're allowed to change the transaction settings of the JDBC Connection.
......
Connection con = session.connection();
Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
txObject.setPreviousIsolationLevel(previousIsolationLevel);
}
else {
// Not allowed to change the transaction settings of the JDBC Connection.
......
}
if (definition.isReadOnly() && txObject.isNewSession()) {
// Just set to NEVER in case of a new Session for this transaction.
session.setFlushMode(FlushMode.MANUAL);
}
if (!definition.isReadOnly() && !txObject.isNewSession()) {
// We need AUTO or COMMIT for a non-read-only transaction.
FlushMode flushMode = session.getFlushMode();
if (flushMode.lessThan(FlushMode.COMMIT)) {
session.setFlushMode(FlushMode.AUTO);
txObject.getSessionHolder().setPreviousFlushMode(flushMode);
}
}
Transaction hibTx;
// Register transaction timeout.
int timeout = determineTimeout(definition);
if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
// Use Hibernate's own transaction timeout mechanism on Hibernate 3.1+
// Applies to all statements, also to inserts, updates and deletes!
hibTx = session.getTransaction();
hibTx.setTimeout(timeout);
hibTx.begin();
}
else {
// Open a plain Hibernate transaction without specified timeout.
//创建并开始事务
hibTx = session.beginTransaction();
}
// Add the Hibernate transaction to the session holder.
//把hibtx事务放到txobject里面,原因是因为这个SessionHolder会和线程绑定
txObject.getSessionHolder().setTransaction(hibTx);
// Register the Hibernate Session's JDBC Connection for the DataSource, if set.
if (getDataSource() !=
null) {
Connection con = 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);
}
// Bind the session holder to the thread.
//如果是新的SessionHolder,把它和线程绑定
if (txObject.isNewSessionHolder()) {
TransactionSynchronizationManager.bindResource(getSessionFactory(), txObject.getSessionHolder());
}
//SessionHolder的状态标识,你的Transaction是一个线程中的session取得的
txObject.getSessionHolder().setSynchronizedWithTransaction(true);
}
catch (Exception ex) {
if (txObject.isNewSession()) {
try {
if (session.getTransaction().isActive()) {
session.getTransaction().rollback();
}
}
catch (Throwable ex2) {
logger.debug("Could not rollback Session after failed transaction begin", ex);
}
finally {
SessionFactoryUtils.closeSession(session);
}
}
throw new CannotCreateTransactionException("Could not open Hibernate Session for transaction", ex);
}
}
相关文章推荐
- 在一个js文件中引用另一js文件(chrome插件亦适用)
- Simhash相似哈希算法
- Spacemacs org-reveal 创建网页版presentation
- 欢迎使用CSDN-markdown编辑器
- C++:Regex正则表达式
- Linux下文件夹相关操作
- Majority Element
- font-size属性的继承
- 数据结构和算法学习笔记-3
- HTMLParser介绍
- Deep Learning笔记1
- JS DOM编程艺术——JS综合实例—— JS学习笔记2015-7-29(第92天)
- iOS 隐藏状态栏
- [Android优化进阶] 提高ListView性能的技巧
- iOS"Request failed: unacceptable content-type: text/html"
- Andriod实现刮刮卡的效果
- shell脚本学习知识点(二)
- hd1232 修路最少(并查集问题)
- CSS基础篇
- [Leetcode] Bitwise And of numbers range