版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40788630/article/details/83003903
基于xml的声明式事务管理是通过在配置文件中使用tx命名空间来配置事务
一、在eclipse中创建chapter05的web项目,在项目的lib目录下导入所需的包:
二、将chapter04中的代码全部复制到chapter05的src目录下,并在AccountDao接口中创建一个转账方法transfer(),创建完成后的代码如下所示:
package com.itheima.jdbc;
import java.util.List;
public interface AccountDao {
//添加
public int addAccount(Account account) ;
//更新
public int upAccount(Account account) ;
//删除
public int deleteAccount(int id) ;
//通过id查询单个账号
public Account findAccountById(int id);
//查询所有账号
public List<Account> findAllAccount();
//转账方法
public void transfer(String outUser,String inUser,double money);
}
三、在其实现类AccountDaoImpl中实现transfer方法,编辑后的代码如下:
/**
* 转账操作,其中outUser是汇款人,inUser是收款人,money是转账金额
*/
@Override
public void transfer(String outUser, String inUser, double money) {
//收款操作
this.jdbcTemplate.update("update account set balance = balance + ? where username = ?",money,inUser);
//收款操作
this.jdbcTemplate.update("update account set balance = balance - ? where username = ?",money,outUser);
}
四、修改配置文件applicationContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!-- 1.配置数据源 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<!-- 数据库驱动 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<!-- 连接数据库的url -->
<property name="url" value="jdbc:mysql://localhost/spring" />
<!-- 连接数据库的用户名 -->
<property name="username" value="root" />
<!-- 连接数据库的用户密码 -->
<property name="password" value="itcast" />
</bean>
<!-- 2.配置JDBC模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 默认使用数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 3.定义一个名为accountDao的bean -->
<bean id="accountDao" class="com.itheima.jdbc.AccountDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<!-- 4.事务管理器,依赖于数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 5.编写通知:对事务进行增强(通知),需要编写对切入点和具体执行事务细节 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- name:*表示任意方法名称 -->
<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" />
</tx:attributes>
</tx:advice>
<!-- 6.编写aop,让spring自动对目标生成代理,需要使用AspectJ的表达式 -->
<aop:config>
<!-- 切入点 -->
<aop:pointcut expression="execution(* com.itheima.jdbc.*.*(..))" id="txPointCut" />
<!-- 切面:将切入点与通知整合 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut" />
</aop:config>
</beans>
在上面这个文件中,首先启用了Spring配置文件的aop,tx和context3个命名空间,然后定义了id为transactionManager的事务管理器,接下来通过编写的通知来声明事务,最后通过声明AOP的方式让Spring自动生成代理
五、在com.itheima.jdbc包中,创建测试类TransactionTest,并在类中编写测试方法xmlTest(),如下所示:
package com.itheima.jdbc;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TransactionTest {
@Test
public void xmlTest() {
ApplicationContext cast = new ClassPathXmlApplicationContext("applicationContext.xml");
AccountDao accountDao = (AccountDao) cast.getBean("accountDao");
//调用实例中的转账方法
accountDao.transfer("rose", "joy", 100.0);
System.out.println("转账成功了!");
}
}
在上面的程序,在获取AccountDao实例后,调用了实例中的转账方法,由rose向joy的账户转入100元,如果在配置文件中所声明的事务代码能够起作用,那么在整个转账方法执行完毕后应该会发生变化,
首先查看account表中的数据,如下图所示:
然后执行操作,操作结果如下:
接着再次查看account表中的数据:
六、接下来测试一下事务处理对于错误的处理功能
首先在AccountDaoImpl实现类的transfer方法中添加一个除零错误,具体代码如下:
public void transfer(String outUser, String inUser, double money) {
//收款操作
this.jdbcTemplate.update("update account set balance = balance + ? where username = ?",money,inUser);
int i=1/0;
//收款操作
this.jdbcTemplate.update("update account set balance = balance - ? where username = ?",money,outUser);
}
重新运行程序,结果如下:
接着查询数据库,发现并未发生改变
说明事务管理机制起到了作用,是第一步的·转入操作进行了回滚