首页 > 技术文章 > spring-tx 事物

zhuyapeng 2020-10-28 14:42 原文

/*
* 事物开启步骤:
* 1.导入包:spring-tx。
* 2.确定目标对象:哪些方法要加事物
* 3.确定加强方式 DataSourceTransactionManager
* 4.开始织入,aop。
*
*
*
* 编程式事务控制三大对象
PlatformTransactionManager
TransactionDefinition
TransactionStatus
*
* TransactionDefinition 是事务的定义信息对象,里面有如下方法:
* int getIsolationLevel() 获得事务的隔离级别
* int getPropogationBehavior() 获得事务的传播行为
* int getTimeout() 获得超时时间
* boolean isReadOnly() 是否只读
*
*
* TransactionStatus 接口提供的是事务具体的运行状态,方法介绍如下。
* boolean hasSavepoint() 是否存储回滚点
* boolean isCompleted() 事务是否完成
* boolean isNewTransaction() 是否是新事务
* boolean isRollbackOnly() 事务是否回滚
* */

xml配置事物:
1.包文件
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

2.bean配置文件

<?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:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation=
               "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.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 id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db1"/>
        <property name="user" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <bean id="userDao" class="cn.web.dao.impl.UserDaoImpl">
        <property name="jdbcTemplate" ref="jdbcTemplate"></property>
    </bean>

    <!--切面目标对象:对server里面所有方法加事物-->
    <bean id="userServer" class="cn.web.server.impl.UserServerImpl">
        <property name="dao" ref="userDao"></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="*"></tx:method>
        </tx:attributes>
    </tx:advice>

    <!--织入 将目标对象 通知关联上-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* cn.web.server.UserServer.*(..))"></aop:pointcut>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"></aop:advisor>
    </aop:config>
</beans>

3.controller入口代码:

import cn.web.server.UserServer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/*
* 事物开启步骤:
* 1.导入包:spring-tx。
* 2.确定目标对象:哪些方法要加事物
* 3.确定加强方式 DataSourceTransactionManager
* 4.开始织入,aop。
*
*
*
* 编程式事务控制三大对象
    PlatformTransactionManager
    TransactionDefinition
    TransactionStatus
*
* TransactionDefinition 是事务的定义信息对象,里面有如下方法:
*   int getIsolationLevel()    获得事务的隔离级别
*   int getPropogationBehavior()    获得事务的传播行为
*   int getTimeout()    获得超时时间
*   boolean isReadOnly()    是否只读
*
*
* TransactionStatus 接口提供的是事务具体的运行状态,方法介绍如下。
*   boolean hasSavepoint()    是否存储回滚点
*   boolean isCompleted()    事务是否完成
*   boolean isNewTransaction()    是否是新事务
*   boolean isRollbackOnly()    事务是否回滚
* */
public class MainController {
    public static void main(String[] args) {
        ApplicationContext context=new ClassPathXmlApplicationContext("applictionContext.xml");
        UserServer userServer = (UserServer) context.getBean("userServer");
        userServer.transfer();
    }
}

4:server层

import cn.web.dao.UserDao;
import cn.web.domain.User;
import cn.web.server.UserServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

public class UserServerImpl implements UserServer {

    private UserDao dao;

    public void setDao(UserDao dao) {
        this.dao = dao;
    }

    public List<User> findAll() {
        return dao.findAll();
    }

    public void transfer() {
        dao.update(1,"88899");
        int i=1/0;
        dao.update(2,"88899");
    }

}
import cn.web.domain.User;

import java.util.List;

public interface UserServer {
    List<User> findAll();
    void transfer();
}

5.dao层

import cn.web.dao.UserDao;
import cn.web.domain.User;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserDaoImpl implements UserDao {

    private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<User> findAll() {
        String sql="SELECT * FROM USER";



        List<User> list =new ArrayList<User>();
        User user=new User();
        user.setId(1);
        user.setPassword("123");
        user.setUsername("admin");
        list.add(user);
        return list;
    }

    public int update(int id, String password) {
        String sql="UPDATE USER SET PASSWORD=? WHERE ID=?";
        int update = jdbcTemplate.update(sql, password, id);
        return update;
    }
}
import cn.web.domain.User;

import java.util.List;

public interface UserDao {
    List<User> findAll();

    int update(int id,String password);
}

 

注解配置:只列出不同

1.配置

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

    <!--开启组件扫描-->
    <context:component-scan base-package="cn.web.anno"></context:component-scan>

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db1"/>
        <property name="user" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>



    <!--切面对象:需要加的事物-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!--事物注解驱动-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

2.server层

import cn.web.anno.dao.UserDao;
import cn.web.anno.domain.User;
import cn.web.anno.server.UserServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service("userServer")
public class UserServerImpl implements UserServer {

    @Autowired
    private UserDao dao;

    public List<User> findAll() {
        return dao.findAll();
    }

    @Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)
    public void transfer() {
        dao.update(1,"666");
//        int i=1/0;
        dao.update(2,"666");
    }

}

 

推荐阅读