Spring 支持两种方式事务管理
- 编程式的事务管理
通过TransactionTemplate手动管理事务(几乎没有人用)
在实际应用中很少使用,原因是要修改原来的代码,加入事务管
- 理代码 (侵入性 )
使用XML或注解配置声明式事务
Spring的声明式事务是通过AOP实现的(环绕通知)
开发中经常使用(代码侵入性最小)–推荐使用!
第一步:添加依赖
新建web工程,spring4_day03_transaction,导入jar(核心4+2,数据库驱动,连接池、测试包,jdbc和事务的两个)和配置文件:
以转账的方式,进行详细的描述spring中的事务
第二步:创建业务逻辑代码
建立DAO和service层,编写转账的业务代码:
DAO层(注意下面实现spring对数据库的修改继承JdbcDaoSupport类)
//数据层
public class AccountDao extends JdbcDaoSupport{
/ /转出
public void out(String name ,double money){
String sql ="update account set money = money-? where name =?" ;
super. getJdbcTemplate(). update(sq1, money,name);
}
//转入
public void in(String name ,double money){
String sql ="update account set money = money+? where name =?";
super. getJdbcTemplate() . update(sql, money,name);
}
}
service层
//注入dao
private AccountDao accountDao;
public void setAccountDao(AccountDao accountDao) {
this .accountDao = accountDao;
}
public void transfer( String outAccountName , String inAccountName,double money){
accountDao. outAccount (outAccountName , money);
int a =1/0;
accountDao. inAccount ( inAccountName , money);
}
第三步:在xml里面配置连接池和bean
配置xml(c3p0连接池和bean)
<1--引入外部的属性配置文件locat ion:类路径下面的文件的名字-->
context:property-placeholder location="db. properties"/>
<1--配置c3p0 --)
<bean id="datatSource" class= "com. mchange. v2. c3p0. ComboPooledDataSource">
<property name="driverCLass" value= "${jdbc . driverClass}"/>
<property name= "jdbcUrL" value= "${jdbc.urL}"/>
<property name- "user" value "${jdbc.username}"/>
<property name= "password" value= "${jdbc. password}"/>
</bean>
cbean idm "accountDao" classm "cn. yonqi. spring. transat ion. dao. AccounDao">
<property name="dataSource"" ref= "datatSource"></property>
</bean>
//配置service层的bean,并以属性注入的方式,向父类JdbcDaoSupport进行注入配置的连接池
<bean id"accountservice" class- "cn. yanqi. spring. transat ion. service . AccountService">
<property name="accounDao" ref= "accountDaad"></property>
</bean>
第四步:在xml中引入命名空间
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
第五步:配置advice通知
配置Advice通知,spring提供了Around通知类TransactionInterceptor。
可以配置为:
<bean id=”transactionInterceptor” class=” org.springframework.transaction.interceptor.TransactionInterceptor”></bean>
但Spring为简化事务的配置,提供了tx:advice来代替上面的配置,也可以理解为该标签是spring为你实现好了的事务的通知增强方案。
具体 的配置为:
<!-- 具体的平台事务管理器: jdbc的一>
<bean id= "transactionManager" class= "org. springframework . jdbc . datasource . DataSourceTransactionManager">
<!--需要注入数据源-->
<property name= "dataSource" ref= "dataSource"/>
< /bean>
<tx:advice id= "txAdvice" transaction- manager= "transact ionManager">
<!--配2置事务的具体策略 (事务的属性)一- >
<tx:attributes>
<!--配置某方法的事务的属性
name方法的名字
isolation:事务的隔离级别默认值是default,使用数据库默认的隔离级别
propagation:事务的传播行为,默认值REQUIRED,同个事务
timeout:事务的超时间(单位是秒),默认值- 1,使用数据库默认的超时间
read-only:事务是否只读,默认值false,可读写。该操作只是查询的时候,设置为true。
rollback- for:指定哪些异常可以回滚,其他的不指定的都不会滚
no- rollback- for :指定哪些异常不回装(没事务),其他的都回装。
-->
<tx: method name="transfer"
isolation= "DEFAUL T" propagation= "REQUIRED" timeout="-1" read-only= "false"
rollback-for=" no-rollback-for=""
/>
<!-- xm]配置事务的属性支持通配符
比如save* ,你的业务方法必须以save开头,比如叫saveBook,自动被事务管理
//换句话说:以后用这个规则酒遗事务,那么你的业务方法名字不能乱写,必须满足该规则。
-->
<!-- <tx:method name= "save*"/>
<tx: method name= "update "/>
<tx:method name= ”delete* "/>
<tx:method name="find*" read-only="true"/>
-->
</tx:attributes>
</tx:advice>
第六步:配置切入点和切面
<!--配置aop:切入点和切面-->
<aop:config>
<!--切入点-->
<aop: pointcut expression= "bean( *Service)" id="txPointcut"/>
<!--切面->
<aop: advisor advice-ref- "txAdvice" pointcut-ref- "txPointcut"/>
</aop:config>
第七步:测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicat ionContext .xml")
public class AccountServiceTest {
@Autowired
private AccountService accountService;
@Test
public void testTran(){
accountService. transfer("Rose", "Jack", 100);
System. out .println("转帐成功");
}
}