2021.10.15 Spring中的事务 案例

目录

1.编程式事务管理(手动编写代码完成事务管理):

2.声明式事务管理(不需要手动编写代码,配置):

1)Xml配置(aop)的方式完成事务管理

 2)注解配置(aop)的方式完成事务管理

3.pox.xml中的相关依赖


创建一个数据表,有a,b两个数据,a,b各有2000元

        

若a向b转100,则现在a为1900,b为2100

此时在Spring事务管理

 创建com.mz.mapper.UserMapper接口

public interface UserMapper {
    public void decrease(Integer id, Double money);//转出
    public void increase(Integer id, Double money);//转入
}

 创建com.mz.mapper.impl.UserMapperImpl

public class UserServiceImpl implements UserService {
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper){
        this.userMapper = userMapper;
    }

    @Override
    public void transfer(Integer fromId, Integer toId, Double money) {
        userMapper.decrease(fromId,money);//转出
        userMapper.increase(toId,money);//转入
    }
}

创建com.mz.service.UserService接口

public interface UserService {
    //转账
    public void transfer(Integer fromId,Integer toId,Double money);
}

创建com.mz.service.impl.UserSServcieImpl类实现上面接口

public class UserServiceImpl implements UserService {
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper){
        this.userMapper = userMapper;
    }

    @Override
    public void transfer(Integer fromId, Integer toId, Double money) {
        userMapper.decrease(fromId,money);//转出
        userMapper.increase(toId,money);//转入
    }
}

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: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/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->

    <!--    引入配置文件-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    <!--    引入数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${db.username}"></property>
        <property name="password" value="${db.password}"></property>
        <property name="url" value="${db.url}"></property>
        <property name="driverClassName" value="${db.driverClassName}"></property>
    </bean>
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->

<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
    <bean id="userMapper" class="com.mz.mapper.impl.UserMapperImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="userService" class="com.mz.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"></property>
    </bean>

</beans>

创建测试类实现

public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService =
                (UserService)applicationContext.getBean("userService");

        userService.transfer(1,2,100d);
    }
}

此时出现结果为:

 a为1900,b为2100,现在是正常的流程,但如果在a给b转账的时候出现意外

就如这种状况,此时运行程序,会出现:

你会发现,转出的方法执行,转入的未执行,即a减少100元,但b没有变化 ,因此我们需要一个方法解决这种错误。

这时候的话就需要给它搭配一个事务。在Spring中给我们提供两种方式

1.编程式事务管理(手动编写代码完成事务管理):

com.mz.service.impl.UserServiceimpl类

public class UserServiceImpl  implements UserService {
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper){
        this.userMapper = userMapper;
    }

    //事务模板对象
    private TransactionTemplate transactionTemplate;

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

//    @Override
//    public void transfer(Integer fromId, Integer toId, Double money) {
//        userMapper.decrease(fromId,money);//转出
//        int i = 1/0;
//        userMapper.increase(toId,money);//转入
//    }

    @Override
    public void transfer(final Integer fromId, final Integer toId, final Double money) {
        //手动编程式事务(了解)
        transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus status) {
                userMapper.decrease(fromId, money);//转出
                //int i = 1 / 0;
                userMapper.increase(toId, money);//转入
            }
        });
    }
}

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: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/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->

    <!--    引入配置文件-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    <!--    引入数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${db.username}"></property>
        <property name="password" value="${db.password}"></property>
        <property name="url" value="${db.url}"></property>
        <property name="driverClassName" value="${db.driverClassName}"></property>
    </bean>
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
    <!--    事务平台管理器-->
    <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="userMapper" class="com.mz.mapper.impl.UserMapperImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="userService" class="com.mz.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"></property>
        <property name="transactionTemplate" ref="transactionTemplate"></property>
    </bean>

</beans>

 此时,a为1800,b为2100

若正常运行,,a为1700,b为2200。

若发生异常,,此时,方法都不执行。

2.声明式事务管理(不需要手动编写代码,配置):

1)Xml配置(aop)的方式完成事务管理

com.mz.service.impl.UserServiceImpl

public class UserServiceImpl  implements UserService {
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper){
        this.userMapper = userMapper;
    }


    @Override
    public void transfer(Integer fromId, Integer toId, Double money) {
        userMapper.decrease(fromId,money);//转出
        //int i = 1/0;
        userMapper.increase(toId,money);//转入
    }
}

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

    <!--    引入配置文件-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    <!--    引入数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${db.username}"></property>
        <property name="password" value="${db.password}"></property>
        <property name="url" value="${db.url}"></property>
        <property name="driverClassName" value="${db.driverClassName}"></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="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>
            <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>
        </tx:attributes>
    </tx:advice>

    <!--    配置事务切面-->
    <aop:config>
        <aop:pointcut id="txPc" expression="execution(* com.qf.service.impl.*ServiceImpl.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"></aop:advisor>
    </aop:config>

<!--    &lt;!&ndash;    事务模板对象&ndash;&gt;-->
<!--    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">-->
<!--        <property name="transactionManager" ref="transactionManager"></property>-->
<!--    </bean>-->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
    <bean id="userMapper" class="com.mz.mapper.impl.UserMapperImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="userService" class="com.mz.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"></property>
<!--        <property name="transactionTemplate" ref="transactionTemplate"></property>-->
    </bean>

</beans>

 此时a为1700,b为2200

正常运行,则,a为1600,b为2300。

异常运行,则,a,b不变,方法不执行。

 2)注解配置(aop)的方式完成事务管理

com.mz.service.impl.UserServletImpl

@Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = true)
public class UserServiceImpl  implements UserService {
    private UserMapper userMapper;

    public void setUserMapper(UserMapper userMapper){
        this.userMapper = userMapper;
    }


    @Transactional(isolation = Isolation.DEFAULT,propagation = Propagation.REQUIRED,readOnly = false)
    @Override
    public void transfer(Integer fromId, Integer toId, Double money) {
        userMapper.decrease(fromId,money);//转出
        int i = 1/0;
        userMapper.increase(toId,money);//转入
    }


}

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


    <!--    引入配置文件-->
    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    <!--    引入数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="${db.username}"></property>
        <property name="password" value="${db.password}"></property>
        <property name="url" value="${db.url}"></property>
        <property name="driverClassName" value="${db.driverClassName}"></property>
    </bean>
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
    <!--    事务平台管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!--    开启注解配置事务-->
    <tx:annotation-driven></tx:annotation-driven>
<!--********************************************************************************************************************-->
    <!-- 配置事务通知 -->
<!--    <tx:advice id="txAdvice" transaction-manager="transactionManager">-->
<!--        <tx:attributes>-->
<!--            <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false"/>-->
<!--            <tx:method name="find*" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="true"/>-->
<!--        </tx:attributes>-->
<!--    </tx:advice>-->
<!--    &lt;!&ndash;    配置事务切面&ndash;&gt;-->
<!--    <aop:config>-->
<!--        <aop:pointcut id="txPc" expression="execution(* com.mz.service.impl.*ServiceImpl.*(..))"/>-->
<!--        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"></aop:advisor>-->
<!--    </aop:config>-->
<!--*******************************************************************************************************************-->
<!--    &lt;!&ndash;    事务模板对象&ndash;&gt;-->
<!--    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">-->
<!--        <property name="transactionManager" ref="transactionManager"></property>-->
<!--    </bean>-->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
<!-- ———————————————————————————————————————————————————————————————————————————————————————————————————————————————— -->
    <bean id="userMapper" class="com.mz.mapper.impl.UserMapperImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <bean id="userService" class="com.mz.service.impl.UserServiceImpl">
        <property name="userMapper" ref="userMapper"></property>
<!--        <property name="transactionTemplate" ref="transactionTemplate"></property>-->
    </bean>

</beans>

 此时a为1600,b为2300

正常运行,则,a为1500,b为2400。

出现异常的话则,a,b方法不执行。

3.pox.xml中的相关依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.10</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.10</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.3.10</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.6</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
        </dependency>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值