手动方式
在这个模式下,spring的底层是用transactionTemplate进行管理的,具体流程如下:
1.在service的实现类中注入transactionTemplate
2.配置transactionTemplate,实现注入
首先service要注入事务模板,发现没有,所以要去配置事务模板
然后事务模板又需要注入事务管理器,发现没有,去配置事务管理器
然后事务管理器又需要数据源才有事务,所以注入数据源
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置数据源
c3p0的
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_tx"></property>
<property name="user" value="root"></property>
<property name="password" value="529558445"></property>
</bean>
<!--配置dao-->
<bean id="accountDao" class="com.zm.daoImpl.AccountDaoImpl">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置service-->
<bean id="accountService" class="com.zm.serviceImpl.AccountServiceImpl">
<!--注入dao-->
<property name="accountDao" ref="accountDao"></property>
<!--注入transactionTemplate-->
<property name="transactionTemplate" ref="transactionTemplate"></property>
</bean>
<!--配置transactionTemplate-->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<!--模板中要使用到事务管理器
所以要注入事务管理器
-->
<property name="transactionManager" ref="transactionManager"></property>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--然后管理器需要事务,事务又是从连接中获得的
所以要注入数据源
-->
<property name="dataSource" ref="dataSource"></property>
</bean>
</beans>
3.测试类(无异常情况)
4.测试类(发生异常)
数据库结果没有发生改变,事务回滚了
半自动
spring提供管理事务的代理工厂bean:TransactionProxyFactoryBean
1.service的实现类
2.配置文件(基本都在这里做了)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置数据源
c3p0的
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_tx"></property>
<property name="user" value="root"></property>
<property name="password" value="529558445"></property>
</bean>
<!--配置dao-->
<bean id="accountDao" class="com.zm.daoImpl.AccountDaoImpl">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置service-->
<bean id="accountService" class="com.zm.serviceImpl.AccountServiceImpl">
<!--注入dao-->
<property name="accountDao" ref="accountDao"></property>
</bean>
<!--配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--然后管理器需要事务,事务又是从连接中获得的
所以要注入数据源
-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置service的代理-->
<bean id="proxyFactoryBean" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!--proxyInterfaces 接口-->
<property name="proxyInterfaces" value="com.zm.service.AccountService"/>
<!--target 目标类-->
<property name="target" ref="accountService"/>
<!--事务管理器-->
<property name="transactionManager" ref="transactionManager"/>
<!--事务属性(事务详情\事务定义)-->
<property name="transactionAttributes">
<props>
<!--key值是确定哪些方法使用当前事务配置
标签里面的参数是配置详情的,具体格式如下:
PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
传播行为,隔离级别 ,是否只读,异常回滚,异常提交(发生异常也要提交事务)
-->
<!--这里采用默认的传播行为和默认的隔离级别-->
<prop key="transfer">PROPAGATION_REQUIRED,ISOLATION_DEFAULT</prop>
</props>
</property>
</bean>
</beans>
3.测试类(没有异常情况)
结果
转账成功
4.测试类(有异常)
数据库结果没有改变,事务回滚了
5.测试类(采用+Exception)
结果(有异常)
数据库结果,仍旧发生改变
6.测试类(加上只读属性,操作没有异常情况)
在配置文件加上只读
数据库没有改变
这两种方式虽然能够实现事务管理,但是方法多起来的时候就会显得配置麻烦,所以spring会有自己的全自动事务管理。东西都是越学越简单,但是底层的东西还是要了解如何执行的,就像前面写的AOP操作一样