歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Spring中事務管理淺談

Spring中事務管理淺談

日期:2017/3/1 10:38:25   编辑:Linux編程

Spring中對事務的聲明式管理

拿一個XML舉例

[html]
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="
  7. http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
  8. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
  9. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
  10. 事務管理目標Service
  11. <bean id="fooService" class="x.y.service.DefaultFooService"/>
  12. 切面配置,配置了切入點是執行FooService下的所有方法 和 切入點調用的通知器為txAdvice
  13. <aop:config>
  14. <aop:pointcut id="fooServiceOperation" expression="execution(* x.y.service.FooService.*(..))"/>
  15. <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/>
  16. </aop:config>
  17. 該通知器的具體配置,所使用的事務管理器,所配置的事務規則
  18. <tx:advice id="txAdvice" transaction-manager="txManager">
  19. <!-- the transactional semantics... -->
  20. <tx:attributes>
  21. <!-- all methods starting with 'get' are read-only -->
  22. <tx:method name="get*" read-only="true"/>
  23. <!-- other methods use the default transaction settings (see below) -->
  24. <tx:method name="*"/>
  25. </tx:attributes>
  26. </tx:advice>
  27. 所選用的事務管理器,和作為啟動參數塞入的dataSource
  28. <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
  29. <property name="dataSource" ref="dataSource"/>
  30. </bean>
  31. 連接數據庫的dataSource
  32. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
  33. <property name="driverClassName" value="Oracle.jdbc.driver.OracleDriver"/>
  34. <property name="url" value="jdbc:oracle:thin:@rj-t42:1521:elvis"/>
  35. <property name="username" value="scott"/>
  36. <property name="password" value="tiger"/>
  37. </bean>
  38. </beans>

Spring中對事務管理的底層實現

以上的方法,選用了Spring本身自帶的JDBC的事務控制器做處理。

相關代碼集中在DataSourceTransactionManager中

比如,事務的取得並且將取得的事務捆綁進當前線程中

[java]
  1. @Override
  2. protected Object doGetTransaction() {
  3. DataSourceTransactionObject txObject = new DataSourceTransactionObject();
  4. txObject.setSavepointAllowed(isNestedTransactionAllowed());
  5. ConnectionHolder conHolder =
  6. (ConnectionHolder) TransactionSynchronizationManager.getResource(this.dataSource);
  7. txObject.setConnectionHolder(conHolder, false);
  8. return txObject;
  9. }

在比如事務的開始,

[java]
  1. /**
  2. * This implementation sets the isolation level but ignores the timeout.
  3. */
  4. @Override
  5. protected void doBegin(Object transaction, TransactionDefinition definition) {
  6. DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
  7. Connection con = null;
  8. try {
  9. if (txObject.getConnectionHolder() == null ||
  10. txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
  11. Connection newCon = this.dataSource.getConnection();
  12. if (logger.isDebugEnabled()) {
  13. logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
  14. }
  15. txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
  16. }
  17. txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
  18. con = txObject.getConnectionHolder().getConnection();
  19. Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
  20. txObject.setPreviousIsolationLevel(previousIsolationLevel);
  21. // Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
  22. // so we don't want to do it unnecessarily (for example if we've explicitly
  23. // configured the connection pool to set it already).
  24. if (con.getAutoCommit()) {
  25. txObject.setMustRestoreAutoCommit(true);
  26. if (logger.isDebugEnabled()) {
  27. logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
  28. }
  29. con.setAutoCommit(false);
  30. }
  31. txObject.getConnectionHolder().setTransactionActive(true);
  32. int timeout = determineTimeout(definition);
  33. if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
  34. txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
  35. }
  36. // Bind the session holder to the thread.
  37. if (txObject.isNewConnectionHolder()) {
  38. TransactionSynchronizationManager.bindResource(getDataSource(), txObject.getConnectionHolder());
  39. }
  40. }
  41. catch (Exception ex) {
  42. DataSourceUtils.releaseConnection(con, this.dataSource);
  43. throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
  44. }
  45. }

等等這裡就不多說了,起個頭。

Copyright © Linux教程網 All Rights Reserved