Spring提供了對事務的聲明式事務管理,只需要在配置文件中做一些配置,即可把操作納入到事務管理當中,解除了和代碼的耦合。
Spring聲明式事務管理,核心實現就是基於Aop。
Spring聲明式事務管理是粗粒度的事務控制,只能給整個方法應用事務,不可以對方法的某幾行應用事務。
Spring聲明式事務管理器類:
Jdbc技術:DataSourceTransactionManager
Hibernate技術:HibernateTransactionManager
1.xml方式聲明事務
引入tx名稱空間
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"></property> <property name="jdbcUrl" value="jdbc:mysql:///student"/> <property name="user" value="root"/> <property name="password" value="juaner767"/> <property name="initialPoolSize" value="3"/> <property name="maxPoolSize" value="6"/> <property name="maxStatements" value="100"/> <property name="acquireIncrement" value="2"/> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg ref="dataSource"/> </bean> <bean id="studentDao" class="com.juaner.spring.tx.StudentDao"> <property name="jdbcTemplate" ref="jdbcTemplate"/> </bean> <bean id="studentService" class="com.juaner.spring.tx.StudentService"> <property name="studentDao" ref="studentDao"/> </bean> <!--spring聲明式事務管理控制--> <!--配置事務管理器類--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--配置事務增強(如何管理事務,只讀、讀寫...)--> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="*save*" read-only="false"/> <tx:method name="get*" read-only="true"/> </tx:attributes> </tx:advice> <!--aop配置,攔截哪些方法(切入點表達式,攔截上面的事務增強)--> <aop:config> <aop:pointcut id="pt" expression="execution(* com.juaner.spring.tx.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/> </aop:config> </beans>
2.注解方式聲明事務
開啟注解掃描
<!--事務管理器類--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--開啟注解掃描--> <context:component-scan base-package="com.juaner.spring.tx"/> <!--注解方式實現事務--> <tx:annotation-driven transaction-manager="txManager"/>
使用注解
@Transactional public void save(Student student){ this.studentDao.save(student); int i = 1/0; this.studentDao.save(student); }
如果@Transactional
應用到方法上,該方法使用事務;
應用到類上,類的方法使用事務,
定義到父類上,執行父類的方法時使用事務;
3.事務屬性
@Transactional( readOnly = false, //讀寫事務 timeout = -1 , //事務的超時時間,-1為無限制 noRollbackFor = ArithmeticException.class, //遇到指定的異常不回滾 isolation = Isolation.DEFAULT, //事務的隔離級別,此處使用后端數據庫的默認隔離級別 propagation = Propagation.REQUIRED //事務的傳播行為 )
其中,事務的傳播行為propagation
Propagation.REQUIRED,業務方法需要在一個事務中運行。如果方法運行時,已經處在一個事務中,那么加入到該事務,否則為自己創建一個新的事務。
Propagation.REQUIRES_NEW,不管是否存在事務,業務方法總會為自己發起一個新的事務。如果方法已經運行在一個事務中,則原有事務會被掛起,新的事務會被創建,直到方法執行結束,新事務才算結束,原先的事務才會恢復執行。