spring 事物管理

一、什么是事物?

  • 事物就是把一系列的动作当做一个独立的工作单元,这些动作要么全部完成,要么完成不了

  • 特点:原子性,隔离性,持久性,一致性

  • 分类:

    编程式事务管理

    • 将事务管理代码嵌到业务方法中来控制事务的提交和回滚
    • 缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码

    声明式事务管理

    • 将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。

    • 通过Spring AOP框架声明式事务管理

二、实现(一)

  • 任务描述:模拟银行转账的程序,要求在转账时通过Spring对事务进行控制

  • 数据库:

    create DATABASE if not exists db_spring charset utf8 collate utf8_general_ci;
    use db_spring;
    #创建客户信息表
    create table if not exists customer(
    id int(10) not null PRIMARY KEY AUTO_INCREMENT comment'id',
    username VARCHAR(50) not null comment'username',
    balance decimal not null comment'金额'
    )engine=innodb default CHARSET=utf8;
    #插入客户
    insert into customer values
    (null,'韩庚',100),
    (null,'韩红',990),
    (null,'韩畅',550)
    
  1. 转账接口类

    public interface AccountDao {
    	/**
    	 * 转账方法
    	 * @param outUser 转账人
    	 * @param inUser 收款人
    	 * @param money  金额
    	 */
    	public void transfer(String outUser, String inUser, Double money);
    }
    
  2. 转账实现类

    public class AccountDaoImpl implements AccountDao {
    //引用jdbcTemplate
    	private JdbcTemplate jdbcTemplate;
    //setter方法
    	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    		this.jdbcTemplate = jdbcTemplate;
    	}
    
    	@Override
    	public void transfer(String outUser, String inUser, Double money) {
    		// TODO Auto-generated method stub
    //		收款人
    		jdbcTemplate.update("update customer set balance=balance+ ? where username=?", money, inUser);
    //		转账人
    		jdbcTemplate.update("update customer set balance=balance-? where username=?", money, outUser);
    	}
    
    }
    

    JdbcTemplate是Spring对JDBC的封装,目的是使JDBC更加易于使用,我们只需要提供SQL语句和提取结果

  3. 配置文件

    	<!-- 配置数据库文件 -->
    	<context:property-placeholder
    		location="db.properties" />
    	<!--配置数据库连接池 -->
    	<bean id="dataSource"
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName" value="${jdbc.driver}" />
    		<property name="url" value="${jdbc.url}" />
    		<property name="username" value="${jdbc.username}" />
    		<property name="password" value="${jdbc.password}" />
    	</bean>
    	<!-- 配置jdbcTemplate模板 -->
    	<bean id="jdbcTemplate"
    		class="org.springframework.jdbc.core.JdbcTemplate">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    	<!-- 注册实现类bean -->
    	<bean id="accountDao" class="com.ruanyuan.dao.impl.AccountDaoImpl">
    		<!-- 将jdbcTmplate注入 -->
    		<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 -->
    	<aop:config>
    		<aop:pointcut
    			expression="execution(* com.ruanyuan.dao.*.*(..))" id="point" />
    		<aop:advisor advice-ref="txAdvice" pointcut-ref="point" />
    	</aop:config>
    </beans>
    
  4. 测试类

    public class TxTest {
    	@Test
    	public void test3() {
    		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    //		获取AccountDao实例
    		AccountDao accountDao = (AccountDao) context.getBean("accountDao");
    		accountDao.transfer("韩庚","韩红",100.0);
    		System.out.println("success");
    	}
    }
    
    

三、实现(二):注解

  1. 接口类

    public interface AccountService {
    	/**
    	 * 转账方法
    	 * @param inUser 收款
    	 * @param outUser 转账
    	 * @param money 金额
    	 */
    	public void transfer(String inUser, String outUser, Double money);
    }
    
  2. 实现类

    @Service("ax")
    public class AccountServiceImpl implements AccountService {
    	@Resource(name = "jdbcTemplate")  //匹配配置文件中jdbcTmpalte
    	private JdbcTemplate jdbcTemplate;
    
    	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    		this.jdbcTemplate = jdbcTemplate;
    	}
    //实现事物
    	@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, readOnly = false)
    	public void transfer(String inUser, String outUser, Double money) {
    		// TODO Auto-generated method stub
    
    //	收款人
    		jdbcTemplate.update("update customer set balance=balance+ ? where username=?", money, inUser);
    //	转账人
    		jdbcTemplate.update("update customer set balance=balance-? where username=?", money, outUser);
    	}
    
    }
    
  3. 配置文件

    	<!-- 导入数据库信息 -->
    	<context:property-placeholder
    		location="db.properties" />
    	<!-- 配置连接池 -->
    	<bean id="dataSource"
    		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    		<property name="driverClassName" value="${jdbc.driver}" />
    		<property name="url" value="${jdbc.url}" />
    		<property name="username" value="${jdbc.username}" />
    		<property name="password" value="${jdbc.password}" />
    	</bean>
    	<!-- 扫描包,使注解生效 -->
    	<context:component-scan
    		base-package="com.ruanyuan.service" />
    	<!-- 注册事物管理驱动 -->
    	<tx:annotation-driven
    		transaction-manager="transactionManager" />
    	<!-- 配置jdbcTemplate模板 -->
    	<bean id="jdbcTemplate"
    		class="org.springframework.jdbc.core.JdbcTemplate">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    
    	<!-- 配置事物管理器 -->
    	<bean id="transactionManager"
    		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    		<property name="dataSource" ref="dataSource"></property>
    	</bean>
    
  4. 测试类

    public class AnnotationTest {
    	@Test
    	public void test3() {
    		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-annotation.xml");
    //		获取AccountDao实例
    		AccountService accountService = (AccountService) context.getBean("ax");
    		accountService.transfer("韩庚","韩红",100.0);
    		System.out.println("success");
    	}
    }
    

    四、事物的传播特性

    多个事务方法相互调用时,事务如何在这些方法间传播。spring支持7种事务传播行为:

    • propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,最常见。
    • propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
    • propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
    • propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
    • propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    • propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
    • propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值