JavaEE企业级 Spring事务管理 基于xml的声明式事务

版权声明:本文为博主原创文章,未经博主允许不得转载。 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);
	}

重新运行程序,结果如下:

接着查询数据库,发现并未发生改变

说明事务管理机制起到了作用,是第一步的·转入操作进行了回滚

猜你喜欢

转载自blog.csdn.net/qq_40788630/article/details/83003903