Spring全XML实现AOP和IOC和事务管理效果-----Spring框架

package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("accountService")
//写在类上所有的方法都应用事务
public class AccountServiceImpl implements AccountService
{
    @Resource(name = "accountDao")
    private AccountDao accountDao;
    @Override
    //数据库三大读问题
    //脏读:读取到还没有提交到数据库的数据,叫做脏读(读到内存里面没有commit的数据)
    //不可重复读:在同一个事务中,第一次和第二次读到的数据不一样(在同一个事务中读到的数据前后不一致)
    //幻读:读到的数据是假的(只要A事务和B事务在同时进行时,永远都会幻读)
    //脑子里想象的数据和真实数据不一样,就是幻读,只要多个事务并发,一定会幻读
    //多个事务并发一定会幻读
    //读未提交:会读内存中的数据,不可重复读,因为事务并发会导致事务中读到的信息前后不一致,导致幻读
    //读提交:不会读内存中的数据,仅读取数据库commit了的数据,仍然会因为事务并发读到前后不一致的信息,导致幻读
    //可重复读:不会读内存中的数据,仅读取commit数据,在事务未结束前,数据库读取到的缓存信息始终不变,但是会导致幻读(因为其他事务已经修改了数据库信息)
    //序列化:事务必须排队执行,不支持并发,解决了幻读问题
    public void transfer(String Actno, String toActno, double money)
    {
        //开启事务
        //需要控制事务,因为在这个方法中要完成所有的转账业务
        //查询转出账户余额是否充足
        Account account = accountDao.selectByAccountNo(Actno);
        if(account.getBalance() < money)
        {
            throw new RuntimeException("余额不足");
        }
        Account toAccount = accountDao.selectByAccountNo(toActno);
        account.setBalance(account.getBalance() - money);
        toAccount.setBalance(toAccount.getBalance() + money);
        int update = accountDao.update(account);
        //模拟异常信息导致中断业务
//        String s = null;
//        s.toString();
        update = update + accountDao.update(toAccount);
        //提交事务
        //遇到异常回滚事务
        if(update != 2)
        {
            throw new RuntimeException("转账失败,请联系银行");
        }
    }
}
package com.powernode.bank.service.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import com.powernode.bank.service.AccountService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service("accountService")
//写在类上所有的方法都应用事务
public class AccountServiceImpl implements AccountService
{
    @Resource(name = "accountDao")
    private AccountDao accountDao;
    @Override
    //数据库三大读问题
    //脏读:读取到还没有提交到数据库的数据,叫做脏读(读到内存里面没有commit的数据)
    //不可重复读:在同一个事务中,第一次和第二次读到的数据不一样(在同一个事务中读到的数据前后不一致)
    //幻读:读到的数据是假的(只要A事务和B事务在同时进行时,永远都会幻读)
    //脑子里想象的数据和真实数据不一样,就是幻读,只要多个事务并发,一定会幻读
    //多个事务并发一定会幻读
    //读未提交:会读内存中的数据,不可重复读,因为事务并发会导致事务中读到的信息前后不一致,导致幻读
    //读提交:不会读内存中的数据,仅读取数据库commit了的数据,仍然会因为事务并发读到前后不一致的信息,导致幻读
    //可重复读:不会读内存中的数据,仅读取commit数据,在事务未结束前,数据库读取到的缓存信息始终不变,但是会导致幻读(因为其他事务已经修改了数据库信息)
    //序列化:事务必须排队执行,不支持并发,解决了幻读问题
    public void transfer(String Actno, String toActno, double money)
    {
        //开启事务
        //需要控制事务,因为在这个方法中要完成所有的转账业务
        //查询转出账户余额是否充足
        Account account = accountDao.selectByAccountNo(Actno);
        if(account.getBalance() < money)
        {
            throw new RuntimeException("余额不足");
        }
        Account toAccount = accountDao.selectByAccountNo(toActno);
        account.setBalance(account.getBalance() - money);
        toAccount.setBalance(toAccount.getBalance() + money);
        int update = accountDao.update(account);
        //模拟异常信息导致中断业务
//        String s = null;
//        s.toString();
        update = update + accountDao.update(toAccount);
        //提交事务
        //遇到异常回滚事务
        if(update != 2)
        {
            throw new RuntimeException("转账失败,请联系银行");
        }
    }
}
package com.powernode.bank.dao.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao
{
    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    @Override
    public Account selectByAccountNo(String actno)
    {
        String sql = "select actno,balance from t_act where actno = ?";
        Account account = jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Account.class),actno);
        return account;
    }

    @Override
    public int update(Account account)
    {
        String sql = "update t_act set balance = ? where actno = ?";
        int update = jdbcTemplate.update(sql, account.getBalance(), account.getActno());
        return update;
    }
}
package com.powernode.bank.dao.impl;

import com.powernode.bank.dao.AccountDao;
import com.powernode.bank.pojo.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;

@Repository("accountDao")
public class AccountDaoImpl implements AccountDao
{
    @Resource(name = "jdbcTemplate")
    private JdbcTemplate jdbcTemplate;
    @Override
    public Account selectByAccountNo(String actno)
    {
        String sql = "select actno,balance from t_act where actno = ?";
        Account account = jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper<>(Account.class),actno);
        return account;
    }

    @Override
    public int update(Account account)
    {
        String sql = "update t_act set balance = ? where actno = ?";
        int update = jdbcTemplate.update(sql, account.getBalance(), account.getActno());
        return update;
    }
}
<?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/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">
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:13306/spring6"></property>
        <property name="username" value="root"></property>
        <property name="password" value="abc123"></property>
    </bean>
    <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>
    <context:component-scan base-package="com.powernode.bank"></context:component-scan>
<!--    配置通知,需要TX命名空间,开启TX命名空间才可以使用(事务使用)-->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<!--        配置通知的相关属性-->
<!--        通知就是具体的增强代码-->
        <tx:attributes>
<!--            之前讲的所有属性都可以在这个标签配置-->
            <tx:method name="transfer" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="modify*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="query*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="select*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="find*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
        </tx:attributes>
    </tx:advice>
<!--    配置切面-->
    <aop:config>
<!--        配置切点-->
        <aop:pointcut id="transactionPointCut" expression="execution(* com.powernode.bank..*(..))"/>
<!--        配置切面(通知加上切点)-->
        <aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointCut"></aop:advisor>
    </aop:config>
</beans>
<?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/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">
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:13306/spring6"></property>
        <property name="username" value="root"></property>
        <property name="password" value="abc123"></property>
    </bean>
    <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>
    <context:component-scan base-package="com.powernode.bank"></context:component-scan>
<!--    配置通知,需要TX命名空间,开启TX命名空间才可以使用(事务使用)-->
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
<!--        配置通知的相关属性-->
<!--        通知就是具体的增强代码-->
        <tx:attributes>
<!--            之前讲的所有属性都可以在这个标签配置-->
            <tx:method name="transfer" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="modify*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="query*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="select*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
            <tx:method name="find*" propagation="REQUIRED" rollback-for="java.lang.Throwable"/>
        </tx:attributes>
    </tx:advice>
<!--    配置切面-->
    <aop:config>
<!--        配置切点-->
        <aop:pointcut id="transactionPointCut" expression="execution(* com.powernode.bank..*(..))"/>
<!--        配置切面(通知加上切点)-->
        <aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointCut"></aop:advisor>
    </aop:config>
</beans>
package com.powernode.bank.Test;

import com.powernode.bank.service.AccountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test
{
    private static final Logger logger = LoggerFactory.getLogger(Test.class);
    @org.junit.Test
    public void TestXMLTransaction()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        AccountService accountService = context.getBean("accountService", AccountService.class);
        try
        {
            accountService.transfer("act-002","act-001",10000);
            logger.info("转账成功");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
package com.powernode.bank.Test;

import com.powernode.bank.service.AccountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test
{
    private static final Logger logger = LoggerFactory.getLogger(Test.class);
    @org.junit.Test
    public void TestXMLTransaction()
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        AccountService accountService = context.getBean("accountService", AccountService.class);
        try
        {
            accountService.transfer("act-002","act-001",10000);
            logger.info("转账成功");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值