spring中提供了对事务管理的封装,可以通过xml配置文件配置,或者注解配置
模拟一个用户转账的过程
1.导入相应的jar包
2.关于dao中代码
package com.lee.dao;
import org.springframework.jdbc.core.JdbcTemplate;
public class UserDao {
//封装的jdbc模板通过spring配置文件创建
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//用户a减100的方法
public void lessMoney(){
String sql = "update user set money = money - ? where userid = ?";
int num = jdbcTemplate.update(sql,100,"admin");
System.out.println(num + "===========");
}
//用户b加100的方法
public void addMoney(){
String sql = "update user set money = money + ? where userid = ?";
int num = jdbcTemplate.update(sql,100,"root");
System.out.println(num + "===========");
}
}
3.关于service代码
package com.lee.service;
import com.lee.dao.UserDao;
public class UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//模拟转账过程
public void countMoney(){
//调用用户a减100的方法
userDao.lessMoney();
int num = 100 / 0; //让后面的操作不执行
//调用用户b加100的方法
userDao.addMoney();
}
}
在service中,执行转账过程中,模拟了一个出现异常的情况。
4.XML中配置
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.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-3.2.xsd">
<!-- 配置c3p0 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///sun" />
<property name="user" value="root" />
<property name="password" value="sunshine" />
</bean>
<bean id="userDao" class="com.lee.dao.UserDao">
<!-- userDao通过jdbc模板操作数据库 -->
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<bean id="userService" class="com.lee.service.UserService">
<property name="userDao" ref="userDao" />
</bean>
<!-- 配置jdbc模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 有参构造方法中调用了setDataSource方法 ,把c3p0的到dataSource传进去-->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源,指定了事务管理器对哪一个数据库的操作 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务增强(用AOP形式增强到需要用事务的方法中) -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 事务的匹配规则,针对哪一个方法增加事务 ,count*代表以count开头的方法都增加事务-->
<tx:method name="count*"/>
</tx:attributes>
</tx:advice>
<!-- 配置AOP -->
<aop:config>
<!-- 切入点,在那个地方用增强 -->
<aop:pointcut expression="execution(* com.lee.service.UserService.*(..))" id="pointCut"/>
<!-- 切面 ,把增强用到切入点上-->
<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
</aop:config>
</beans>
关于事务管理器,spring对不同的持久化框架有不同的接口实现
以上就利用XML配置文件形式配置好了事务。运行代码,中间出现了错误,事务回滚,数据库未改变。
5.利用注解形式配置事务
XML中关于事务的配置:
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 开起事务管理器注解扫描 (指定事务管理器)-->
<tx:annotation-driven transaction-manager="transactionManager"/>
在需要用到事务的类上方添加注解
@Transactional
这样在此类中的方法都添加了事务操作。