探討一下spring攔截器中的數據庫操做和事務管理。
你們知道spring中的事務管理是經過AOP代理來實現的,對被代理對象的每一個方法進行攔截,在方法執行前啓動事務,方法執行完後根據是否有異常和異常的種類進行提交或回滾。
如 果要在方法執行前或後或拋出異常後加上一個本身的攔截器,或者一個環繞攔截器,在攔截器中執行一些操做,好比執行一些數據庫操做,記錄一些信息,這些操做 經過調用一個服務類的方法來執行,這個方法也在spring事務管理攔截器的管理之下,那麼這個記錄方法須要在另外一個事務中進行,而不是與被攔截方法在同 一個事務中,否則若是被攔截方法拋出異常須要回滾時,所做的記錄也會被回滾,固然有時候確實須要同時回滾,那就要放在同一個事務中。
這 和本身的攔截器和事務管理的攔截器的執行順序有必定關係,spring事務管理攔截器是一個環繞通知,在被攔截方法執行前啓動事務,執行後完成事務,若是 本身的攔截器被spring事務管理攔截器包圍在裏面,那麼在本身的攔截器運行時,spring已經啓動了一個事務,若是你的記錄信息方法須要與被攔截方 法同在一個事務中,將你的記錄信息方法的事務傳播屬性設爲默認的REQUIRED就能夠了;
若是你記錄信息的方法須要單獨的一個事務環境,那就 要把事務傳播屬性設爲REQUIRES_NEW了,這樣spring事務管理器會新建一個事務,而且新建一個session鏈接,由於一個數據庫鏈接不可 能同時有兩個事務,記錄信息完了提交事務而且把新建的session鏈接關閉,本身的攔截器退出後繼續執行被攔截的方法或它的事務處理。
相 反若是本身的攔截器在spring事務管理攔截器的外面,那麼記錄信息的方法會在一個單獨的事務中執行,並提交,無論它的事務傳播屬性是 REQUIRES_NEW仍是REQUIRED,由於與被攔截方法的事務處理沒有交叉,而且可使用同一個session鏈接若是是 OpenSessionInViewFilter。
因此若是記錄信息和被攔截方法要在不一樣事務中執行,分別提交,那麼最好將本身的攔截 器設在spring事務管理器攔截器的外面;若是須要將記錄信息和被攔截方法在同一個事務中處理,必須將本身的攔截器被包圍在spring事務管理攔截器 中,而且記錄信息方法的事務傳播屬性爲默認的REQUIRED。
設置攔截器的執行順序可讓攔截器處理類實現 org.springframework.core.Ordered接口,在spring配置文件的AOP設置中設定本身的攔截器和spring事務管理 攔截器的執行順序,將本身的攔截的序號排在spring事務管理的前面,就能夠將該攔截器放到事務管理攔截器的外面執行了,對於before通知方式會先 於事務管理攔截器執行,對於after returning和after和after throwing通知方式會後於事務管理攔截器的執行,對於arount通知方式會包圍事務管理攔截器執行。
下面是一個異常攔截器的例子。
有 位朋友提到在spring異常攔截器中更新數據不可以提交,作了一下測試,測試環境基本是這樣:一個用戶登陸的功能,spring對service中的每 個方法進行事務管理,在用戶檢測的service方法上同時加上一個異常攔截器,當用戶不存在或密碼不正確時用戶檢測方法會拋出異常,異常攔截器捕獲到該 異常,同時記錄一些日誌。
spring配置文件相關: java
攔截器類:web
service方法中的事務傳播屬性都設爲要求新建事務,spring事務管理切面攔截器的order設爲1,而log攔截器的 order設爲2,這意味着這兩個要同時執行時,先執行事務攔截器,後執行log攔截器,因爲事務管理是一個環繞通知(around),其實是log攔 截器被包圍在事務管理攔截器中。spring
一個不正確的用戶登陸時,打印的日誌:數據庫
03:35:16,562 DEBUG OpenSessionInViewFilter:253 - Using SessionFactory 'sessionFactory' for OpenSessionInViewFilterexpress
03:35:16,562 DEBUG OpenSessionInViewFilter:196 - Opening single Hibernate Session in OpenSessionInViewFilterapache
03:35:16,562 DEBUG SessionFactoryUtils:333 - Opening Hibernate Sessionsession
03:35:16,562 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.orm.hibernate3.SessionHolder@1fee2db] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] to thread [http-8088-Processor25]app
03:35:16,562 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1fee2db] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] bound to thread [http-8088-Processor25]ide
03:35:16,562 DEBUG HibernateTransactionManager:390 - Found thread-bound Session [org.hibernate.impl.SessionImpl@dfbabd] for Hibernate transaction測試
03:35:16,578 DEBUG HibernateTransactionManager:292 - Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@5cd7f9]
03:35:16,578 DEBUG HibernateTransactionManager:320 - Creating new transaction with name [com.hbs.customer.CustomerService.customerLogin]
03:35:16,578 DEBUG HibernateTransactionManager:440 - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@dfbabd]
03:35:16,578 DEBUG HibernateTransactionManager:510 - Exposing Hibernate transaction as JDBC transaction [org.apache.commons.dbcp.PoolableConnection@1501026]
03:35:16,578 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@1672c01] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] to thread [http-8088-Processor25]
03:35:16,578 DEBUG TransactionSynchronizationManager:219 - Initializing transaction synchronization
03:35:16,578 DEBUG TransactionInterceptor:275 - Getting transaction for [com.hbs.customer.CustomerService.customerLogin]
用戶登陸
03:35:16,578 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1fee2db] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] bound to thread [http-8088-Processor25]
03:35:16,578 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1fee2db] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] bound to thread [http-8088-Processor25]
03:35:16,578 DEBUG HibernateTemplate:354 - Found thread-bound Session for HibernateTemplate
03:35:16,578 DEBUG SQL:393 - select this_.CUSTOMER_ID as CUSTOMER1_5_0_, this_.CUSTOMER_GROUP_ID as CUSTOMER2_5_0_, this_.CUSTOMER_PASSWORD as CUSTOMER3_5_0_, this_.CUSTOMER_NAME as CUSTOMER4_5_0_, this_.CUSTOMER_DESCRIPTION as CUSTOMER5_5_0_, this_.CUSTOMER_KIND as CUSTOMER6_5_0_, this_.CUSTOMER_SEX as CUSTOMER7_5_0_, this_.PHONE as PHONE5_0_, this_.MOBILE as MOBILE5_0_, this_.ADDRESS as ADDRESS5_0_, this_.EMAIL as EMAIL5_0_, this_.CONFIRM_TYPE as CONFIRM12_5_0_, this_.CREATE_TIME as CREATE13_5_0_, this_.GROUP_TIME as GROUP14_5_0_, this_.FIRST_TIME as FIRST15_5_0_, this_.LAST_TIME as LAST16_5_0_, this_.LOGIN_COUNT as LOGIN17_5_0_, this_.CREDIT_VALUE as CREDIT18_5_0_, this_.CUMULATE_VALUE as CUMULATE19_5_0_, this_.STATUS as STATUS5_0_, this_.NOTES as NOTES5_0_ from hbs.hbs_customer this_ where this_.CUSTOMER_ID=? and this_.CUSTOMER_PASSWORD=?
03:35:16,593 DEBUG HibernateTemplate:378 - Not closing pre-bound Hibernate Session after HibernateTemplate
03:35:16,593 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@1fee2db] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] bound to thread [http-8088-Processor25]
03:35:16,593 DEBUG HibernateTransactionManager:390 - Found thread-bound Session [org.hibernate.impl.SessionImpl@dfbabd] for Hibernate transaction
03:35:16,593 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.jdbc.datasource.ConnectionHolder@1672c01] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] bound to thread [http-8088-Processor25]
03:35:16,593 DEBUG HibernateTransactionManager:292 - Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@5ec940]
03:35:16,593 DEBUG HibernateTransactionManager:358 -
Suspending current transaction, creating new transaction with name [com.hbs.eventlog.EventLogService.eventLog]03:35:16,593 DEBUG TransactionSynchronizationManager:272 - Clearing transaction synchronization
03:35:16,593 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.orm.hibernate3.SessionHolder@1fee2db] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] from thread [http-8088-Processor25]
03:35:16,609 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@1672c01] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] from thread [http-8088-Processor25]
03:35:16,609 DEBUG HibernateTransactionManager:428 -
Opened new Session [org.hibernate.impl.SessionImpl@eeb406] for Hibernate transaction03:35:16,609 DEBUG HibernateTransactionManager:440 - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@eeb406]
03:35:16,609 DEBUG HibernateTransactionManager:510 - Exposing Hibernate transaction as JDBC transaction [org.apache.commons.dbcp.PoolableConnection@8543aa]
03:35:16,609 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@16d03ba] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] to thread [http-8088-Processor25]
03:35:16,609 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.orm.hibernate3.SessionHolder@fbfa2] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] to thread [http-8088-Processor25]
03:35:16,609 DEBUG TransactionSynchronizationManager:219 - Initializing transaction synchronization
03:35:16,609 DEBUG TransactionInterceptor:275 - Getting transaction for [com.hbs.eventlog.EventLogService.eventLog]
03:35:16,625 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@fbfa2] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] bound to thread [http-8088-Processor25]
03:35:16,625 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@fbfa2] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] bound to thread [http-8088-Processor25]
03:35:16,625 DEBUG HibernateTemplate:354 - Found thread-bound Session for HibernateTemplate
03:35:16,625 DEBUG SQL:393 - select hotel0_.HOTEL_ID as HOTEL1_3_0_, hotel0_.HOTEL_NAME as HOTEL2_3_0_, hotel0_.DESCRIPTION as DESCRIPT3_3_0_, hotel0_.CHARACTERISTIC as CHARACTE4_3_0_, hotel0_.STAR_CLASS as STAR5_3_0_, hotel0_.ESTABLISH_DATE as ESTABLISH6_3_0_, hotel0_.BUSINESS_LICENSE as BUSINESS7_3_0_, hotel0_.LEGAL_PERSON as LEGAL8_3_0_, hotel0_.ADDRESS as ADDRESS3_0_, hotel0_.PHONE as PHONE3_0_, hotel0_.EMAIL as EMAIL3_0_, hotel0_.INTERNET_ADDRESS as INTERNET12_3_0_, hotel0_.HOTEL_LOG as HOTEL13_3_0_, hotel0_.COPYRIGHT as COPYRIGHT3_0_, hotel0_.NOTES as NOTES3_0_, hotel0_.CUR_ORDERFORM_ID as CUR16_3_0_ from hbs.hbs_hotel hotel0_ where hotel0_.HOTEL_ID=?
03:35:16,625 DEBUG HibernateTemplate:378 - Not closing pre-bound Hibernate Session after HibernateTemplate
03:35:16,625 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@fbfa2] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] bound to thread [http-8088-Processor25]
03:35:16,625 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@fbfa2] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] bound to thread [http-8088-Processor25]
03:35:16,625 DEBUG HibernateTemplate:354 - Found thread-bound Session for HibernateTemplate
03:35:16,625 DEBUG SQL:393 - update hbs.hbs_hotel set HOTEL_NAME=?, DESCRIPTION=?, CHARACTERISTIC=?, STAR_CLASS=?, ESTABLISH_DATE=?, BUSINESS_LICENSE=?, LEGAL_PERSON=?, ADDRESS=?, PHONE=?, EMAIL=?, INTERNET_ADDRESS=?, HOTEL_LOG=?, COPYRIGHT=?, NOTES=?, CUR_ORDERFORM_ID=? where HOTEL_ID=?
03:35:16,640 DEBUG HibernateTemplate:378 - Not closing pre-bound Hibernate Session after HibernateTemplate
03:35:16,640 DEBUG TransactionInterceptor:305 - Completing transaction for [com.hbs.eventlog.EventLogService.eventLog]
03:35:16,640 DEBUG HibernateTransactionManager:776 - Triggering beforeCommit synchronization
03:35:16,640 DEBUG HibernateTransactionManager:789 - Triggering beforeCompletion synchronization
03:35:16,640 DEBUG HibernateTransactionManager:609 - Initiating transaction commit
03:35:16,640 DEBUG HibernateTransactionManager:557 -
Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@eeb406]03:35:16,671 DEBUG HibernateTransactionManager:802 - Triggering afterCommit synchronization
03:35:16,671 DEBUG HibernateTransactionManager:818 - Triggering afterCompletion synchronization
03:35:16,671 DEBUG TransactionSynchronizationManager:272 - Clearing transaction synchronization
03:35:16,671 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.orm.hibernate3.SessionHolder@fbfa2] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] from thread [http-8088-Processor25]
03:35:16,671 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@16d03ba] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] from thread [http-8088-Processor25]
03:35:16,671 DEBUG HibernateTransactionManager:636 -
Closing Hibernate Session [org.hibernate.impl.SessionImpl@eeb406] after transaction03:35:16,671 DEBUG SessionFactoryUtils:781 - Closing Hibernate Session
03:35:16,671 DEBUG HibernateTransactionManager:870 - Resuming suspended transaction
03:35:16,671 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.orm.hibernate3.SessionHolder@1fee2db] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] to thread [http-8088-Processor25]
03:35:16,671 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@1672c01] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] to thread [http-8088-Processor25]
03:35:16,671 DEBUG TransactionSynchronizationManager:219 - Initializing transaction synchronization
03:35:16,671 DEBUG TransactionInterceptor:320 - Completing transaction for [com.hbs.customer.CustomerService.customerLogin] after exception: com.hbs.common.ResultException: 登陸失敗!用戶名或密碼不正確
03:35:16,671 DEBUG RuleBasedTransactionAttribute:130 - Applying rules to determine whether transaction should rollback on com.hbs.common.ResultException: 登陸失敗!用戶名或密碼不正確
03:35:16,687 DEBUG RuleBasedTransactionAttribute:148 - Winning rollback rule is: RollbackRuleAttribute with pattern [Exception]
03:35:16,687 DEBUG HibernateTransactionManager:789 - Triggering beforeCompletion synchronization
03:35:16,687 DEBUG HibernateTransactionManager:700 - Initiating transaction rollback
03:35:16,687 DEBUG HibernateTransactionManager:576 - Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@dfbabd]
03:35:16,687 DEBUG HibernateTransactionManager:818 - Triggering afterCompletion synchronization
03:35:16,687 DEBUG TransactionSynchronizationManager:272 - Clearing transaction synchronization
03:35:16,687 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@1672c01] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] from thread [http-8088-Processor25]
03:35:16,687 DEBUG HibernateTransactionManager:643 - Not closing pre-bound Hibernate Session [org.hibernate.impl.SessionImpl@dfbabd] after transaction
03:35:16,687 WARN ActionMapping:74 - Unable to find 'null' forward.
03:35:16,687 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.orm.hibernate3.SessionHolder@1fee2db] for key [org.hibernate.impl.SessionFactoryImpl@1fe3238] from thread [http-8088-Processor25]
03:35:16,687 DEBUG OpenSessionInViewFilter:221 - Closing single Hibernate Session in OpenSessionInViewFilter
03:35:16,687 DEBUG SessionFactoryUtils:781 - Closing Hibernate Session
從 中能夠看出,log異常攔截器在用戶登陸的事務回滾以前截獲異常,在記錄日誌時,日誌記錄的service方法也在spring的事務管理之下,用戶登陸 的事務尚未結束,根據REQUIRES_NEW特性,spring會新開一個事務,這時原來的數據庫鏈接已經在一個事務中,一個鏈接不可能同時有兩個事 務,因此同時新建立一個session鏈接(雖然我使用了OpenSessionInViewFilter,而且session是單例的),日誌記錄就在 新建的事務和session中進行,完了提交,而且會把新建的session鏈接關閉。
而後繼續進行被中斷的用戶登陸的事務管理操做,因爲拋異常spring將用戶登陸的事務回滾。
這樣可以實現預想的功能,可是若是我去掉指定的REQUIRES_NEW,那麼log記錄的操做會繼續在用戶登陸的事務中進行,最後會被一塊兒回滾。
若是我把事務管理的order設爲2,log攔截器的order設爲1,也就是log攔截器在事務管理攔截器的外面,會在事務管理攔截器先後執行完了再執行log的異常攔截器,打印信息以下:
03:53:46,125 DEBUG OpenSessionInViewFilter:253 - Using SessionFactory 'sessionFactory' for OpenSessionInViewFilter
03:53:46,156 DEBUG OpenSessionInViewFilter:196 - Opening single Hibernate Session in OpenSessionInViewFilter
03:53:46,156 DEBUG SessionFactoryUtils:333 - Opening Hibernate Session
03:53:46,265 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] to thread [http-8088-Processor25]
03:53:46,296 INFO ComposableRequestProcessor:144 - Initializing composable request processor for module prefix ''
03:53:46,375 INFO CreateAction:65 - Initialize action of type: org.springframework.web.struts.DelegatingActionProxy
03:53:46,406 INFO JdbcTransactionObjectSupport:60 - JDBC 3.0 Savepoint class is available
03:53:46,406 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] bound to thread [http-8088-Processor25]
03:53:46,406 DEBUG HibernateTransactionManager:390 - Found thread-bound Session [org.hibernate.impl.SessionImpl@c21d01] for Hibernate transaction
03:53:46,406 DEBUG HibernateTransactionManager:292 - Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@1fe6783]
03:53:46,406 DEBUG HibernateTransactionManager:320 - Creating new transaction with name [com.hbs.customer.CustomerService.customerLogin]
03:53:46,421 DEBUG HibernateTransactionManager:440 - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@c21d01]
03:53:46,468 DEBUG HibernateTransactionManager:510 - Exposing Hibernate transaction as JDBC transaction [org.apache.commons.dbcp.PoolableConnection@16c02df]
03:53:46,468 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@30803a] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] to thread [http-8088-Processor25]
03:53:46,468 DEBUG TransactionSynchronizationManager:219 - Initializing transaction synchronization
03:53:46,484 DEBUG TransactionInterceptor:275 - Getting transaction for [com.hbs.customer.CustomerService.customerLogin]
03:53:46,500 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] bound to thread [http-8088-Processor25]
03:53:46,500 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] bound to thread [http-8088-Processor25]
03:53:46,515 DEBUG HibernateTemplate:354 - Found thread-bound Session for HibernateTemplate
03:53:46,531 DEBUG SQL:393 - select this_.CUSTOMER_ID as CUSTOMER1_5_0_, this_.CUSTOMER_GROUP_ID as CUSTOMER2_5_0_, this_.CUSTOMER_PASSWORD as CUSTOMER3_5_0_, this_.CUSTOMER_NAME as CUSTOMER4_5_0_, this_.CUSTOMER_DESCRIPTION as CUSTOMER5_5_0_, this_.CUSTOMER_KIND as CUSTOMER6_5_0_, this_.CUSTOMER_SEX as CUSTOMER7_5_0_, this_.PHONE as PHONE5_0_, this_.MOBILE as MOBILE5_0_, this_.ADDRESS as ADDRESS5_0_, this_.EMAIL as EMAIL5_0_, this_.CONFIRM_TYPE as CONFIRM12_5_0_, this_.CREATE_TIME as CREATE13_5_0_, this_.GROUP_TIME as GROUP14_5_0_, this_.FIRST_TIME as FIRST15_5_0_, this_.LAST_TIME as LAST16_5_0_, this_.LOGIN_COUNT as LOGIN17_5_0_, this_.CREDIT_VALUE as CREDIT18_5_0_, this_.CUMULATE_VALUE as CUMULATE19_5_0_, this_.STATUS as STATUS5_0_, this_.NOTES as NOTES5_0_ from hbs.hbs_customer this_ where this_.CUSTOMER_ID=? and this_.CUSTOMER_PASSWORD=?
03:53:46,593 DEBUG HibernateTemplate:378 - Not closing pre-bound Hibernate Session after HibernateTemplate
03:53:46,593 DEBUG TransactionInterceptor:320 - Completing transaction for [com.hbs.customer.CustomerService.customerLogin] after exception: com.hbs.common.ResultException: 登陸失敗!用戶名或密碼不正確
03:53:46,609 DEBUG RuleBasedTransactionAttribute:130 - Applying rules to determine whether transaction should rollback on com.hbs.common.ResultException: 登陸失敗!用戶名或密碼不正確
03:53:46,609 DEBUG RuleBasedTransactionAttribute:148 - Winning rollback rule is: RollbackRuleAttribute with pattern [Exception]
03:53:46,609 DEBUG HibernateTransactionManager:789 - Triggering beforeCompletion synchronization
03:53:46,609 DEBUG HibernateTransactionManager:700 - Initiating transaction rollback
03:53:46,609 DEBUG HibernateTransactionManager:576 -
Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@c21d01]03:53:46,609 DEBUG HibernateTransactionManager:818 - Triggering afterCompletion synchronization
03:53:46,609 DEBUG TransactionSynchronizationManager:272 - Clearing transaction synchronization
03:53:46,609 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@30803a] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] from thread [http-8088-Processor25]
03:53:46,625 DEBUG HibernateTransactionManager:643 - Not closing pre-bound Hibernate Session [org.hibernate.impl.SessionImpl@c21d01] after transaction
03:53:46,640 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] bound to thread [http-8088-Processor25]
03:53:46,640 DEBUG HibernateTransactionManager:390 - Found thread-bound Session [org.hibernate.impl.SessionImpl@c21d01] for Hibernate transaction
03:53:46,640 DEBUG HibernateTransactionManager:292 - Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@1f68336]
03:53:46,640 DEBUG HibernateTransactionManager:320 -
Creating new transaction with name [com.hbs.eventlog.EventLogService.eventLog]03:53:46,640 DEBUG HibernateTransactionManager:440 - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@c21d01]
03:53:46,640 DEBUG HibernateTransactionManager:510 - Exposing Hibernate transaction as JDBC transaction [org.apache.commons.dbcp.PoolableConnection@16c02df]
03:53:46,640 DEBUG TransactionSynchronizationManager:166 - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@1205042] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] to thread [http-8088-Processor25]
03:53:46,656 DEBUG TransactionSynchronizationManager:219 - Initializing transaction synchronization
03:53:46,656 DEBUG TransactionInterceptor:275 - Getting transaction for [com.hbs.eventlog.EventLogService.eventLog]
03:53:46,656 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] bound to thread [http-8088-Processor25]
03:53:46,656 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] bound to thread [http-8088-Processor25]
03:53:46,656 DEBUG HibernateTemplate:354 - Found thread-bound Session for HibernateTemplate
03:53:46,656 DEBUG SQL:393 - select hotel0_.HOTEL_ID as HOTEL1_3_0_, hotel0_.HOTEL_NAME as HOTEL2_3_0_, hotel0_.DESCRIPTION as DESCRIPT3_3_0_, hotel0_.CHARACTERISTIC as CHARACTE4_3_0_, hotel0_.STAR_CLASS as STAR5_3_0_, hotel0_.ESTABLISH_DATE as ESTABLISH6_3_0_, hotel0_.BUSINESS_LICENSE as BUSINESS7_3_0_, hotel0_.LEGAL_PERSON as LEGAL8_3_0_, hotel0_.ADDRESS as ADDRESS3_0_, hotel0_.PHONE as PHONE3_0_, hotel0_.EMAIL as EMAIL3_0_, hotel0_.INTERNET_ADDRESS as INTERNET12_3_0_, hotel0_.HOTEL_LOG as HOTEL13_3_0_, hotel0_.COPYRIGHT as COPYRIGHT3_0_, hotel0_.NOTES as NOTES3_0_, hotel0_.CUR_ORDERFORM_ID as CUR16_3_0_ from hbs.hbs_hotel hotel0_ where hotel0_.HOTEL_ID=?
03:53:46,718 DEBUG HibernateTemplate:378 - Not closing pre-bound Hibernate Session after HibernateTemplate
03:53:46,734 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] bound to thread [http-8088-Processor25]
03:53:46,734 DEBUG TransactionSynchronizationManager:139 - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] bound to thread [http-8088-Processor25]
03:53:46,734 DEBUG HibernateTemplate:354 - Found thread-bound Session for HibernateTemplate
03:53:46,812 DEBUG SQL:393 - update hbs.hbs_hotel set HOTEL_NAME=?, DESCRIPTION=?, CHARACTERISTIC=?, STAR_CLASS=?, ESTABLISH_DATE=?, BUSINESS_LICENSE=?, LEGAL_PERSON=?, ADDRESS=?, PHONE=?, EMAIL=?, INTERNET_ADDRESS=?, HOTEL_LOG=?, COPYRIGHT=?, NOTES=?, CUR_ORDERFORM_ID=? where HOTEL_ID=?
03:53:46,812 DEBUG HibernateTemplate:378 - Not closing pre-bound Hibernate Session after HibernateTemplate
03:53:46,812 DEBUG TransactionInterceptor:305 - Completing transaction for [com.hbs.eventlog.EventLogService.eventLog]
03:53:46,812 DEBUG HibernateTransactionManager:776 - Triggering beforeCommit synchronization
03:53:46,812 DEBUG HibernateTransactionManager:789 - Triggering beforeCompletion synchronization
03:53:46,812 DEBUG HibernateTransactionManager:609 - Initiating transaction commit
03:53:46,812 DEBUG HibernateTransactionManager:557 -
Committing Hibernate transaction on Session [org.hibernate.impl.SessionImpl@c21d01]03:53:46,859 DEBUG HibernateTransactionManager:802 - Triggering afterCommit synchronization
03:53:46,859 DEBUG HibernateTransactionManager:818 - Triggering afterCompletion synchronization
03:53:46,859 DEBUG TransactionSynchronizationManager:272 - Clearing transaction synchronization
03:53:46,859 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@1205042] for key [org.apache.commons.dbcp.BasicDataSource@54cbb9] from thread [http-8088-Processor25]
03:53:46,859 DEBUG HibernateTransactionManager:643 - Not closing pre-bound Hibernate Session [org.hibernate.impl.SessionImpl@c21d01] after transaction
記錄日誌結束
03:53:46,859 WARN ActionMapping:74 - Unable to find 'null' forward.
03:53:46,859 DEBUG TransactionSynchronizationManager:190 - Removed value [org.springframework.orm.hibernate3.SessionHolder@889c4e] for key [org.hibernate.impl.SessionFactoryImpl@cdf872] from thread [http-8088-Processor25]
03:53:46,859 DEBUG OpenSessionInViewFilter:221 - Closing single Hibernate Session in OpenSessionInViewFilter
03:53:46,875 DEBUG SessionFactoryUtils:781 - Closing Hibernate Session
可 以看出,用戶登陸的事務和日誌記錄的事務是先後兩個不相關的事務,而且在日誌記錄事務中並不須要新建session鏈接,而是直接用在 OpenSessionInViewFilter中建立的session。實際上這時也並不須要將propagation設爲REQUIRES_NEW, 使用默認的REQUIRES也照樣可以正常工做。
因此應該將該異常攔截器設在事務管理攔截器的外面,即便用Order接口排在前面。