美文网首页
Spring事务管理

Spring事务管理

作者: 紫荆秋雪_文 | 来源:发表于2019-10-06 23:20 被阅读0次

一、事务管理器 事务管理器.png

二、事务的传播规则

Spring 在 TransactionDefinition 接口中定义了七种事务传播规则,规定了事务方法和事务方法发生嵌套调用时事务如何进行传播

  • PROPAGATION_REQUIRED:若当前没有事务,则新建一个事务,若当前已存在一个事务,则加入到该事务中(最常用操作)。
  • PROPAGATION_SUPPORTS:支持当前事务,若当前没有事务,则以非事务方式执行
  • PROPAGATION_MANDATORY:使用当前事务,若当前没有事务,则抛出异常
  • PROPAGATION_REQUIRES_NEW:新建事务,如果当前存在事务,把当前事务挂起
  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,若当前存在事务,则把当前事务挂起
  • PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常
  • PROPAGATION_NESTED:如当前存在事务,则嵌套在本事务内执行,若没有事务则执行PROPAGATION_REQUIRED类似操作

三、在 applicationContext.xml 中引入事务环境

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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.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">
</beans>

四、转账示例

  • domain
package com.revanwang.tx.domain;


import lombok.Data;

@Data
public class Account {
    private Long    id;
    private Double  balance;
}
  • dao
package com.revanwang.tx.dao.impl;

import com.revanwang.tx.dao.IAccountDAO;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

public class AccountDAOImpl implements IAccountDAO {

    private JdbcTemplate jdbcTemplate;

    public void setDataSource(DataSource dataSource) {
        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }


    @Override
    public void bankIn(Long inId, Double money) {
        String sql = "UPDATE Account SET balance = balance + ? WHERE id = ?";
        this.jdbcTemplate.update(sql, money, inId);
    }

    @Override
    public void bankOut(Long outId, Double money) {
        String sql = "UPDATE Account SET balance = balance - ? WHERE id = ?";
        this.jdbcTemplate.update(sql, money, outId);
    }
}

  • service
package com.revanwang.tx.service.impl;

import com.revanwang.tx.dao.IAccountDAO;
import com.revanwang.tx.service.IAccountService;
import lombok.Setter;

public class AccountServiceImpl implements IAccountService {

    @Setter
    private IAccountDAO accountDAO;

    @Override
    public void bankTrans(Long inId, Long outId, Double money) {

        this.accountDAO.bankIn(inId, money);
        System.out.println(1 / 0);
        this.accountDAO.bankOut(outId, money);

    }
}
  • AccountTest
package com.revanwang.tx;


import com.revanwang.tx.action.AccountAction;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AccountTest {

    @Autowired
    private AccountAction accountAction;

    @Test
    public void testTrans() {
        this.accountAction.bankTrans(10086L, 10010L, (double) 550);
    }

}

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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.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">


    <!--  what:配置事务类型  -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataBaseDB"/>
    </bean>

    <!--  when:当在什么时候做增强  -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="bankTrans"/>
        </tx:attributes>
    </tx:advice>

    <!-- where:在哪些包下的类型中的哪些方法上做增强 -->
    <aop:config>
        <!--切入点-->
        <aop:pointcut id="txPoint" expression="execution(* com.revanwang.tx.service.*Service.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
    </aop:config>

    <!--  引入属性配置文件  -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--配置缓冲池-->
    <bean id="dataBaseDB" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="maxActive" value="${jdbc.maxActive}"/>
    </bean>

    <!--配置DAO-->
    <bean id="accountDAO" class="com.revanwang.tx.dao.impl.AccountDAOImpl">
        <property name="dataSource" ref="dataBaseDB"/>
    </bean>

    <!--配置Service-->
    <bean id="accountService" class="com.revanwang.tx.service.impl.AccountServiceImpl">
        <property name="accountDAO" ref="accountDAO"/>
    </bean>

    <!--配置Action-->
    <bean id="accountAction" class="com.revanwang.tx.action.AccountAction">
        <property name="accountService" ref="accountService"/>
    </bean>

</beans>
tx属性.png

五、转账示例注解

  • applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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.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">


    <!--  what:配置事务类型  -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataBaseDB"/>
    </bean>
    <tx:annotation-driven transaction-manager="txManager"/>

    <!--  引入属性配置文件  -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--配置缓冲池-->
    <bean id="dataBaseDB" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="maxActive" value="${jdbc.maxActive}"/>
    </bean>

    <!--配置DAO-->
    <bean id="accountDAO" class="com.revanwang.tx.dao.impl.AccountDAOImpl">
        <property name="dataSource" ref="dataBaseDB"/>
    </bean>

    <!--配置Service-->
    <bean id="accountService" class="com.revanwang.tx.service.impl.AccountServiceImpl">
        <property name="accountDAO" ref="accountDAO"/>
    </bean>

    <!--配置Action-->
    <bean id="accountAction" class="com.revanwang.tx.action.AccountAction">
        <property name="accountService" ref="accountService"/>
    </bean>

</beans>
  • service
package com.revanwang.tx.service.impl;

import com.revanwang.tx.dao.IAccountDAO;
import com.revanwang.tx.service.IAccountService;
import lombok.Setter;
import org.springframework.transaction.annotation.Transactional;


@Transactional
public class AccountServiceImpl implements IAccountService {

    @Setter
    private IAccountDAO accountDAO;

    @Override
    public void bankTrans(Long inId, Long outId, Double money) {

        this.accountDAO.bankIn(inId, money);
        System.out.println(1 / 0);
        this.accountDAO.bankOut(outId, money);

    }
}

相关文章

网友评论

      本文标题:Spring事务管理

      本文链接:https://www.haomeiwen.com/subject/bwkmuctx.html