在java Spring5通过声明式事务(注解方式)完成一个简单的事务操作中 我们通过注解方式完成了一个事务操作
那么 下面 我还是讲一下 基于xml实现声明式事务的操作 其实在开发过程中 大家肯定都喜欢用注解 因为他方便
这篇文章中的xml方式 大家做个了解就好
还是 我们的这张表 记号他们的余额 然后 我们的项目环境还是延续之前的那个
如果没有看我之前文章的朋友 可以先去看一下 java Spring5 搭建操作数据库事务环境跟着 把项目环境搭建一下
然后 我们来到 senvice 下的 transfAccoSenvice类 修改代码如下
package senvice;
import dao.transfAccoDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class transfAccoSenvice {
@Autowired
private transfAccoDao TransfAccoDao;
//转账方法
public void transferAccounts(int sponsorId, int recipientId, double money){
Boolean paym = pay(money,sponsorId);
if(paym){
int i = 10/0;
income(money,recipientId);
System.out.println("交易完成");
}
}
//支出方法
public Boolean pay(double money,int userId) {
String vacancies = CheckTheBalance(userId);
double vacancie = Double.parseDouble(vacancies);
if(money > vacancie) {
System.out.println("余额不足");
return false;
}
double settleAccounts = (vacancie - money);
TransfAccoDao.updateMoney(String.valueOf(settleAccounts),userId);
return true;
}
//收入方法
public Boolean income(double money,int userId) {
String vacancies = CheckTheBalance(userId);
double vacancie = Double.parseDouble(vacancies);
double settleAccounts = (vacancie + money);
TransfAccoDao.updateMoney(String.valueOf(settleAccounts),userId);
return true;
}
//查询指定用户余额
public String CheckTheBalance(int userId){
return TransfAccoDao.CheckTheBalance(userId);
}
}
还是在transferAccounts中 用0做除数来模仿出一个异常
然后 我们 修改bean.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:context="http://www.springframework.org/schema/context"
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/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="jdbc:mysql:///test" /><!--对应SQLyog里的数据库-->
<property name="username" value="root" /> <!-- 用户名 -->
<property name="password" value="root" /> <!-- 密码 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
<!-- JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource属性-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<context:component-scan base-package="senvice"></context:component-scan>
<context:component-scan base-package="dao"></context:component-scan>
<!-->配置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref= "dataSource"></property>
</bean>
<!-- 配置通知 -->
<tx:advice id="txadvice">
<tx:attributes>
<tx:method name="transfer*"/>
</tx:attributes>
</tx:advice>
<!-- 配置切入点和切面-->
<aop:config>
<aop:pointcut id="pt" expression="execution(* senvice.transfAccoSenvice.*(..))"/>
<aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>
</beans>
关键的几行在于 tx:advic 配置通知 然后 tx:method中 name 我想让他指向的是 transferAccounts 就是我们模仿异常的那个方法 当然 你直接写 name=“transferAccounts” 自然是可以的 但我这个transfer* 表示 锁定所有 以transfer开头的 星号代表模糊搜索
然后 用aop:pointcut配合 切入点表达式 锁定了 senvice下的 transfAccoSenvice 中 所有的函数 *代表所有 (…)点方法参数
其他类 包括测试类 都不需要改
然后 我们打开测试类 运行代码如下
可以看到 我们这里 李四被减去200 打印出 11000 说明 第一段sql已经执行了 但因为事务 异常后应该回滚结果 所以李四的钱不会少 还是11200
我们到数据库中 刷新表并重新打开
可以看到 因为事务回滚 李四的钱并没有少
然后 我们到senvice 下的 transfAccoSenvice 将 int i = 10/0;干掉
然后运行测试类 结果如下
可以看到 没有异常的干涉 两端sql都执行成功了
那么 我们到数据库 刷新表 再重新打开
可以看到 没有异常 事务就正常提交了 我们的交易 也就正常完成啦