Spring(5) Spring对事物的支持

一,事物实例(实现银行转账)

事物的四个条件分别是原子性;一致性;隔离性和持久性。
这个想必大家都知道了,还是先上个实例吧,有例子什么都好理解。
来实现用事物实现银行转账
总体目录:
这里写图片描述
jar包:
这里写图片描述
数据表:
这里写图片描述
BankDao.java:

package com.java1234.dao;

public interface BankDao {

    public void inMoney(int money,int userId);

    public void outMoney(int money,int userId);
}

BankDaoImpl.java:

package com.java1234.dao.impl;

import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import com.java1234.dao.BankDao;

public class BankDaoImpl implements BankDao{

    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;


    public void setNamedParameterJdbcTemplate(
            NamedParameterJdbcTemplate namedParameterJdbcTemplate) {
        this.namedParameterJdbcTemplate = namedParameterJdbcTemplate;
    }

    @Override
    public void inMoney(int money, int userId) {
        // TODO Auto-generated method stub
        String sql="update t_count1 set count=count+:money where userId=:userId";
        MapSqlParameterSource sps=new MapSqlParameterSource();
        sps.addValue("money", money);
        sps.addValue("userId", userId);
        namedParameterJdbcTemplate.update(sql,sps);
    }

    @Override
    public void outMoney(int money, int userId) {
        // TODO Auto-generated method stub
        String sql="update t_count set count=count-:money where userId=:userId";
        MapSqlParameterSource sps=new MapSqlParameterSource();
        sps.addValue("money", money);
        sps.addValue("userId", userId);
        namedParameterJdbcTemplate.update(sql,sps);
    }

}

BankService.java:

package com.java1234.service;

public interface BankService {

    /**
     * 转账方法,A向B转50
     * @param count
     * @param userIdA
     * @param userIdB
     */
    public void transferAccounts(int count,int userIdA,int userIdB);
}

BankServiceImpl.java:

package com.java1234.service.impl;

import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import com.java1234.dao.BankDao;
import com.java1234.service.BankService;


public class BankServiceImpl implements BankService{

    private BankDao bankDao;

    private TransactionTemplate transactionTemplate;

    public void setBankDao(BankDao bankDao) {
        this.bankDao = bankDao;
    }

    public void setTransactionTemplate(TransactionTemplate transactionTemplate) {
        this.transactionTemplate = transactionTemplate;
    }

    @Override
    public void transferAccounts(final int count, final int userIdA, final int userIdB) {
        // TODO Auto-generated method stub
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {

            @Override
            protected void doInTransactionWithoutResult(TransactionStatus arg0) {
                // TODO Auto-generated method stub
                bankDao.outMoney(count, userIdA);
                bankDao.inMoney(count, userIdB);                
            }
        });
    }

}

T.java:

package com.java1234.test;

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

import com.java1234.service.BankService;


public class T {

    private ApplicationContext ac;

    @Before
    public void setUp() throws Exception {
        ac=new ClassPathXmlApplicationContext("beans.xml");
    }

    @Test   
    public void transferAccounts() {
        BankService bankService=(BankService)ac.getBean("bankService");
        bankService.transferAccounts(50, 1, 2);
    }

}

beans.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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
<context:property-placeholder location="jdbc.properties"/>

    <bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
        <constructor-arg ref="dataSource"></constructor-arg>
    </bean>


    <bean id="bankDao" class="com.java1234.dao.impl.BankDaoImpl">
        <property name="namedParameterJdbcTemplate" ref="namedParameterJdbcTemplate"></property>
    </bean> 

    <bean id="bankService" class="com.java1234.service.impl.BankServiceImpl">
        <property name="bankDao" ref="bankDao"></property>
    </bean> 

</beans>

jdbc.properties:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_bank
jdbc.username=root
jdbc.password=123

最终实现转账测试:
这里写图片描述

这里我们发现事物模板入侵到业务代码中了,这样既不美观,也不方便开发。而且事物也有有异常,比如张三减了50,李四没有增加的情况可能会出现。
当当当,这时就提出了编程式事物管理

二,编程式事务管理

Spring 提供的事务模版类是:org.springframework.transaction.support.TransactionTemplate
事务管理器是:org.springframework.jdbc.datasource.DataSourceTransactionManager
这时我对上面的事物进行配置:

  <!-- jdbc事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"></property>
    </bean>

<bean id="bankService" class="com.java1234.service.impl.BankServiceImpl">
        <property name="bankDao" ref="bankDao"></property>
        <property name="transactionTemplate" ref="transactionTemplate"></property>
    </bean> 

这样就实现了编程式事物管理,这样就能自动实现事物的四大特性。

扫描二维码关注公众号,回复: 2563210 查看本文章

三,声明式事务管理(使用XML配置)

这里就接着上面来了
1,第一步,修改BankServiceImpl.java类,让其只有业务代码的内容,如下:

package com.java1234.service.impl;

import com.java1234.dao.BankDao;
import com.java1234.service.BankService;


public class BankServiceImpl implements BankService{

    //引入Dao
    private BankDao bankDao;

    public void setBankDao(BankDao bankDao) {
        this.bankDao = bankDao;
    }


    @Override
    public void transferAccounts(int count, int userIdA, int userIdB) {

        bankDao.outMoney(count, userIdA);
        bankDao.inMoney(count, userIdB);                
    }

}

2,引入声明式事物空间(这个在官方文档找)

<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:context="http://www.springframework.org/schema/context"
    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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

3,配置事物通知

<!-- 配置事务通知 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>  
            <tx:method name="*"/>
        </tx:attributes>  
    </tx:advice>

4,配置事物切面

 <!-- 配置事务切面 -->
    <aop:config>
        <!-- 配置切点 -->
        <aop:pointcut id="serviceMethod" expression="execution(* com.java1234.service.*.*(..))" />
        <!-- 配置事务通知 -->
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethod"/>
    </aop:config>

这样一来就配置OK了!
这里声明式事物管理其实还有一种方法是使用注解配置声明式事务,但是开发中一般用到XMl配置方式,因为这种方式在应对大项目时实用方便,而且不用一个一个配置。

猜你喜欢

转载自blog.csdn.net/m0_37293461/article/details/80764391
今日推荐