Spring 声明式事务

168 阅读1分钟

事务

  • 把一组业务当成一个事务来做;
  • 要么都成功,要么都失败!
  • 事务在项目开发中,十分的重要,涉及到数据的一致性问题,不能马虎!
  • 确保完整性和一致性;

事务ACID原则:

  • 原子性
  • 一致性
  • 隔离性

多个业务可能操作同一个资源,防止数据损坏

  • 持久性

一旦提交,无论系统发生什么问题,结果都不会再被影响,被持久化的写到存储器中!

样例

先引入tx的命名空间

<?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">
</beans>

注入DataSourceTransactionManager,封装事务,配置切入

<?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">
    <import resource="spring-config.xml"/>
    <bean id="peopleMapper" class="com.mybatis.DAO.PeopleMapperImpl">
        <property name="sqlSessionTemplate" ref="sqlSession"/>
    </bean>

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

    <tx:advice id="txAdvice" transaction-manager="transaction">
        <tx:attributes> 
            <tx:method name="add"/>
            <tx:method name="getPeopleList"/>
            <tx:method name="delete"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="txPointcut" expression="execution(* com.mybatis.DAO.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
    </aop:config>
</beans>

Mapper接口

public interface PeopleMapper {
    List<People> getPeopleList();
    int add(People people);
    int delete(int id);
}

mapper实现类

public class PeopleMapperImpl extends SqlSessionDaoSupport implements PeopleMapper{
 //private SqlSessionTemplate sqlSession;
//    //我们的所有操作,都使用sqLSession来执行,在原来,现在都使川sqLSessionTemplate;
//    public void setSqlSession(SqlSessionTemplate sqlSession) {
//        this.sqlSession = sqlSession;
//}

    @Override
    public List<People> getPeopleList() {

        PeopleMapper mapper = getSqlSession().getMapper(PeopleMapper.class);
        mapper.add(new People(13,"Jim",20,"UK"));
        //mapper.delete(7);
    return mapper.getPeopleList();
    }

    @Override
    public int add(People people) {
        PeopleMapper mapper = getSqlSession().getMapper(PeopleMapper.class);
        return mapper.add(people);
    }

    @Override
    public int delete(int id) {
        PeopleMapper mapper = getSqlSession().getMapper(PeopleMapper.class);
        return mapper.delete(id);
    }
}

Mapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.mybatis.DAO.PeopleMapper">
    <select id="getPeopleList" resultType="com.mybatis.pojo.People">
        select * from mybatis.people;
    </select>
    <insert id="add" parameterType="com.mybatis.pojo.People">
        insert into mybatis.people (id, name,age,address) values (#{id},#{name},#{age},#{address});
    </insert>
    <delete id="delete" parameterType="int">
        delete from mybatis.people where id=#{id}
    </delete>
</mapper>

image.png

这样就能避免数据不一致问题,比如删除成功而添加失败的情况就不会出现

bug收集

image.png
but was actually of type 'com.sun.proxy.$Proxy'**

image.png