第五讲:spring的事务管理

什么是事务?

对数据库的一组连贯的操作,事务具有一些特性,自行百度。

Spring中事务的方式:

代码是在第四讲上修改得到的:

1、基于xml文件的声明式事务。

accountDao:
package com.jdbc;

import java.util.List;

public interface AccountDao {

	//添加
	public int addAccount(Account account);
	//更新
	public int updateAccount(Account account);
	//根据id删除
	public int deleteAccount(Account account);
	//通过id查询
	public Account findById(int id);
	//查询所有账户
	public List<Account>findAll();
	//转账
	public void transfer(String outUser,String inUser,Double money);//增加transfer方法
	
}
accountDaoImpl类:
package com.jdbc;

import java.util.List;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public class AccountDaoImpl implements AccountDao {

	//声明JDBCTemplate属性
	private JdbcTemplate jdbcTemplate;
	
	//添加
	@Override
	public int addAccount(Account account) {
		// TODO Auto-generated method stub
		String sql="insert into account(username,balance) values(?,?)";
		Object[] obj=new Object[] {
				account.getUsername(),
				account.getBalance()
		};
		//返回条数影响的
		return this.jdbcTemplate.update(sql,obj);
	}
	
	//更新账户
	@Override
	public int updateAccount(Account account) {
		// TODO Auto-generated method stub
		String sql="update account set username=?,balance=? where id=?";
		Object[] obj=new Object[] {
				account.getUsername(),
				account.getBalance(),
				account.getId()
		};
		return this.jdbcTemplate.update(sql,obj);
	}
	
	//删除账户
	@Override
	public int deleteAccount(Account account) {
		// TODO Auto-generated method stub
		String sql="delete from account where id=?";
		return this.jdbcTemplate.update(sql,account.getId());
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	@Override
	public Account findById(int id) {
		// TODO Auto-generated method stub
		String sql="select * from account where id=?";
		//将account与数据库种的account一一对应
		RowMapper<Account> rowMapper=new BeanPropertyRowMapper<Account>(Account.class);	
		return this.jdbcTemplate.queryForObject(sql, rowMapper,id);
	}

	@Override
	public List<Account> findAll() {
		String sql="select * from account";
		//将account与数据库种的account一一对应
		RowMapper<Account> rowMapper=new BeanPropertyRowMapper<Account>(Account.class);	
		return this.jdbcTemplate.query(sql, rowMapper);
	}

	@Override

	public void transfer(String outUser, String inUser, Double money) {
		// TODO Auto-generated method stub
		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);
		
	}
	
}

测试类:

package com.jdbc;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TransactionTest {

	@Test
	public void xmlTest() {
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
		AccountDao accountDao=(AccountDao) applicationContext.getBean("accountDao");
		accountDao.transfer("tom2", "tom", 100.0);
		/*
			转账方法先在转出账户扣钱,再到转入账户增加金额,这是一个事务,不能只完成其中的一部。
			本例测试后可以去数据库中查看是否在正确。
		*/
		System.out.println("success");
	}
	
	@Test
	public void annotationxmlTest() {
		ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext2-annotation.xml");
		AccountDao accountDao=(AccountDao) applicationContext.getBean("accountDao");
		accountDao.transfer("tom2", "tom", 100.0);
		System.out.println("success");
	}
}

xml文件:除了基本的bean和数据库源的创建,还需要配置事务属性(属性作用自行百度),和aop切面让spring自动生成代理。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
		xmlns:aop="http://www.springframework.org/schema/aop" 
		xmlns:context="http://www.springframework.org/schema/context" 
		xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
						http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-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"><!-- 注明spring版本 -->
    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <!-- 数据库驱动 -->
    	<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>
    <!-- 连接数据库的url -->
    	<property name="url" value="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=Spring"></property>
    <!-- 连接数据库的用户名密码 -->
    	<property name="username" value="sa"></property>
    	<property name="password" value="123"></property>
    </bean>
    <!-- 配置jdbc模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    		<!-- 默认必须使用数据源 -->
    		<property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 定义id为accountDao的bean -->
    <bean id="accountDao" class="com.jdbc.AccountDaoImpl">
    <!-- 将jdbcTemplate 注入到accountDao实例中 -->
    	<property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>
    <!-- 事务管理器,依赖于数据源 -->
    <bean id="transactionManager"
    	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	<property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 编写通知:对事务增强,需要编写对切入点和具体执行事务细节 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
    	<tx:attributes>
    	<!-- 任意方法 -->
    		<tx:method name="*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
    	</tx:attributes>
    </tx:advice>
    <aop:config>
    	<aop:pointcut expression="execution(* com.jdbc.*.*(..))" id="txPointCut"/>
    	<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>    	
    </aop:config>
    
</beans>

2、基于注解的声明式事务:

注解只需要改其中的xml文件,把aop和事务声明删了,加上事务管理驱动器。
xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
		xmlns:aop="http://www.springframework.org/schema/aop" 
		xmlns:context="http://www.springframework.org/schema/context" 
		xmlns:tx="http://www.springframework.org/schema/tx" 
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
						http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-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">
    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <!-- 数据库驱动 -->
    	<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"></property>
    <!-- 连接数据库的url -->
    	<property name="url" value="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=Spring"></property>
    <!-- 连接数据库的用户名密码 -->
    	<property name="username" value="sa"></property>
    	<property name="password" value="123"></property>
    </bean>
    <!-- 配置jdbc模板 -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    		<!-- 默认必须使用数据源 -->
    		<property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 定义id为accountDao的bean -->
    <bean id="accountDao" class="com.jdbc.AccountDaoImpl">
    <!-- 将jdbcTemplate 注入到accountDao实例中 -->
    	<property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>
    <bean id="transactionManager"
    	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	<property name="dataSource" ref="dataSource"></property>
    </bean>
  	<tx:annotation-driven transaction-manager="transactionManager"/>
    
</beans>

accounDaoImpl类:
在xml文件没有配置开启注解管理器是因为在xml文件里配置了accounDaoImpl的bean,并且在该类的transfer方法上增加了事务注解。

代码同xml声明式的事务(第二个Junit测试)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值