Spring声明式事务

Spring声明式事务

一、回顾事务

  • 事务主要涉及在程序开发过程中数据一致性的问题

  • 使用事务来确保数据的完整性和一致性。

事务就是把一系列的动作当成一个独立的工作单元,这些动作要么全部完成,要么全部失败。

事务的四个原则(ACID原则):

  1. 原子性:要么全部成功,要么全部失败

  2. 一致性:一旦所有事务完成,事务就要被提交

  3. 隔离性:可能多个事务会同时处理相同的数据,因此每个事务要与其他事物隔离,放置数据损坏

  4. 持久性:事务一旦完成无论发生什么事情,结果都不会受到影响。

测试一个需要事务的实例:

在接口中添加增加和删除方法:

public interface UserMapper {
    //查询所有用户,返回值为User结果集合
    List<User> getUserList();
​
    int addUser(User user);
    
    int deleteUser(int id);
}public interface UserMapper {
    //查询所有用户,返回值为User结果集合
    List<User> getUserList();
​
    int addUser(User user);
    
    int deleteUser(int id);
}

 

配置mapper文件,故意制造错误将delete写成deletes

<mapper namespace="com.aishimin.dao.UserMapper"><select id="getUserList" resultType="User">
        select *from mybatis.user;
    </select><insert id="addUser" parameterType="User">
        insert into mybatis.user (id,name,pwd)
        values (#{id},#{name},#{pwd});
    </insert><delete id="deleteUser" parameterType="int">
        deletes from mybatis.user where id=#{id};
    </delete></mapper>

 

编写接口实体类:

public class UserMapperImpl implements UserMapper{
​
    private SqlSessionTemplate sqlSession;
​
    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }
​
    @Override
    public List<User> getUserList() {
        User user = new User(5,"小明","haishdiaoa");
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        mapper.addUser(user);
        mapper.deleteUser(5);
        return mapper.getUserList();
    }
​
    @Override
    public int addUser(User user) {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.addUser(user);
    }
​
    @Override
    public int deleteUser(int id) {
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.deleteUser(id);
    }
}

 

测试:

public class MyTest {
    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper mapper = context.getBean("UserMapper", UserMapper.class);
        for(User user:mapper.getUserList()){
            System.out.println(user);
        }
    }
}

 

测试结果:插入成功,但是删除SQL异常

结论:在没有事务参与的前提下,我们发现在进行一些操作的时候如果只有某一些环节出现错误,将会导致我们的数据发生错误,因此引出事务的参与。

二、Spring中的事务管理

Spring中的事务管理分为编程式事务和声明式事务管理。

编程式事务:

  • 将事务代码嵌套到业务方法中来控制事务的提交和回滚。

  • 缺点:必须在每个事务操作业务逻辑中包含额外的事务管理代码

声明式事务管理:

  • 一般使用声明式事务

  • 将事务管理从业务方法中抽离,通过声明的方式来实现事务管理

  • 将事务管理作为横切关注点,通过AOP方法织入。Spring中通过SpringAOP框架支持声明式事务管理。

使用spring管理事务,主要头文件的约束导入:

xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx
https://www.springframework.org/schema/tx/spring-tx.xsd

 

事务管理器:

  • 无论使用哪一种事务管理策略事务管理器都是必须的

  • 事务管理器是Spring的核心事务管理抽象

JDBC事务:

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="datasource"/>
 </bean>

 

配置好事务管理器后去配置事务的通知:

<!--    配置事务通知-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
<!--            配置哪些方法使用什么事务,配置事务的传播特性-->
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="query" propagation="REQUIRED"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

 

Spring事务的传播特性:

Spring默认的事务传播行为是REQUIRED,适合绝大多数情况

配置AOP:

<aop:config>
    <aop:pointcut id="txPoint" expression="execution(* com.aishimin.dao.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPoint"/>
</aop:config>

再次测试:

结果显示如果其中一个SQL出现错误,所有的操作将都不会执行,如果成功的话全部都会成功。

posted @ 2021-03-07 15:04  aishimin  阅读(80)  评论(0)    收藏  举报