spring事务的三种配置应用实例

0.项目结构

具体代码见:https://github.com/xkzhangsan/spring-transaction-practice.git,包括创建表sql在内。

1.编程式事务使用DataSourceTransactionManager git对应版本: v0.0.1

(1)Spring的xml配置:springapp-context.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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <description>Example configuration to get you started.</description>

    <context:component-scan base-package="com.xkzhangsan.tx" />
    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/xkspringmvc"></property>
        <property name="user" value="xktest"></property>
        <property name="password" value="123456"></property>
    </bean>
    
    <bean id="accountDao" class="com.xkzhangsan.tx.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
     
    <bean id="accountService" class="com.xkzhangsan.tx.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
    
    <!-- 配置事务管理器 ,管理器需要事务,事务从Connection获得,连接从连接池DataSource获得 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>    
     

</beans>

(2)AccountServiceImpl

package com.xkzhangsan.tx.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.xkzhangsan.tx.dao.AccountDao;
import com.xkzhangsan.tx.service.AccountService;

public class AccountServiceImpl implements AccountService{
     
    private AccountDao accountDao;
    
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    @Override
    public void transfer(String outer, String inner, int money) {
        DefaultTransactionDefinition transDef = new DefaultTransactionDefinition(); // 定义事务属性
        transDef.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED); // 设置传播行为属性
        TransactionStatus status = dataSourceTransactionManager.getTransaction(transDef); // 获得事务状态
        try {
            // 数据库操作
            accountDao.out(outer, money);
            int i = 1/0;
            accountDao.in(inner, money);
             
            dataSourceTransactionManager.commit(status);// 提交
        } catch (Exception e) {
            dataSourceTransactionManager.rollback(status);// 回滚
        }
    }
 
}

2.声明式事务基于AOP的xml配置 git对应版本: v0.0.2

(1)Spring的xml配置:springapp-context.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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <description>Example configuration to get you started.</description>

    <context:component-scan base-package="com.xkzhangsan.tx" />
    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/xkspringmvc"></property>
        <property name="user" value="xktest"></property>
        <property name="password" value="123456"></property>
    </bean>
    
    <bean id="accountDao" class="com.xkzhangsan.tx.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
     
    <bean id="accountService" class="com.xkzhangsan.tx.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
    
    <!-- 1 事务管理器 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
     
    <!-- 2 事务详情(事务通知)  , 在aop筛选基础上,比如对ABC三个确定使用什么样的事务。例如:AC读写、B只读 等
        <tx:attributes> 用于配置事务详情(属性属性)
            <tx:method name=""/> 详情具体配置
                propagation 传播行为 , REQUIRED:必须;REQUIRES_NEW:必须是新的
                isolation 隔离级别
    -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="transfer" propagation="REQUIRED" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>
     
    <!-- 3 AOP编程,利用切入点表达式从目标类方法中 确定增强的连接器,从而获得切入点 -->
    <aop:config>
        <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.xkzhangsan.tx.service..*.*(..))"/>
    </aop:config>    
     

</beans>

(2)AccountServiceImpl

package com.xkzhangsan.tx.service.impl;

import com.xkzhangsan.tx.dao.AccountDao;
import com.xkzhangsan.tx.service.AccountService;

public class AccountServiceImpl implements AccountService{
     
    private AccountDao accountDao;
     
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    @Override
    public void transfer(String outer, String inner, int money) {
        accountDao.out(outer, money);
        int i=10/0;
        accountDao.in(inner, money);
    }
 
}

3. 声明式事务基于AOP的注解 git对应版本: v0.0.3

(1)Spring的xml配置:springapp-context.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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <description>Example configuration to get you started.</description>

    <context:component-scan base-package="com.xkzhangsan.tx" />
    
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/xkspringmvc"></property>
        <property name="user" value="xktest"></property>
        <property name="password" value="123456"></property>
    </bean>
    
    <bean id="accountDao" class="com.xkzhangsan.tx.dao.impl.AccountDaoImpl">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
     
    <bean id="accountService" class="com.xkzhangsan.tx.service.impl.AccountServiceImpl">
        <property name="accountDao" ref="accountDao"></property>
    </bean>
    
    <!-- 1 事务管理器 -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 2 将管理器交予spring
        * transaction-manager 配置事务管理器
        * proxy-target-class
            true : 底层强制使用cglib 代理
    -->
    <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>    
     

</beans>

(2)AccountServiceImpl

package com.xkzhangsan.tx.service.impl;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.xkzhangsan.tx.dao.AccountDao;
import com.xkzhangsan.tx.service.AccountService;

public class AccountServiceImpl implements AccountService{
     
    private AccountDao accountDao;
     
    public void setAccountDao(AccountDao accountDao) {
        this.accountDao = accountDao;
    }
    @Override
    @Transactional(propagation=Propagation.REQUIRED , isolation = Isolation.DEFAULT)
    public void transfer(String outer, String inner, int money) {
        accountDao.out(outer, money);
        int i=10/0;
        accountDao.in(inner, money);
    }
 
}

参考:https://www.cnblogs.com/ysocean/p/7617620.html

寻找撬动地球的支点(解决问题的方案),杠杆(Java等编程语言)已经有了。xkzhangsan
原文地址:https://www.cnblogs.com/xkzhangsanx/p/11217913.html