关于 Spring 事务 理解(2)

<!-- 创建sessionFactory -->
    <bean>
        <property ref="dataSource"/>
        <property>
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            </props>
        </property>
        <!-- 实体类映射文件 -->
        <property>
            <list>
                <value>classpath*:/domain/*.hbm.xml</value>
            </list>
        </property>
        <property>
            <value>domain</value>
        </property>
        <!-- 实体类 -->
        <property>
            <list>
                <value>domain.UserEntity</value>
            </list>
        </property>
    </bean>

<!-- 创建声明式事务管理 -->
    <bean>
        <property ref="sessionFactory"/>
    </bean>

<!-- 事务通知 -->
    <tx:advice transaction-manager="transactionManager">
        <tx:attributes>
            <!-- propagation配置传播行为,isolation配置隔离方式,表示在方法存在事务的时候直接使用,不存在则创建一个新事务,隔离级别为一个事务可以读取另外一个已提交事务的内容, -->
            <tx:method propagation="REQUIRED" isolation="READ_COMMITTED"/>
        </tx:attributes>
    </tx:advice>

<!-- aop织入通知 -->
    <aop:config>
        <aop:pointcut expression="execution(* service.serviceImpl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOption"/>
    </aop:config>


</beans>

  web.xml (配置session拦截器,他将为每个请求绑定一个session,这个session是hibernateSession和,httpSession不一样,这样他可以有spring自动管理,无需手动开关)

<!-- 为每个请求过程绑定一个HibernateSession,它将由spring自动管理,无需手动开启和关闭 -->
        <filter>
            <filter-name>openSessionInterceptor</filter-name>
            <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>openSessionInterceptor</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>

  在未使用事务管理的时候,同一个事务内的两个数据库操作,一个成功了,就会对数据库产生影响,如果两个操作是互相对应的,比如一个是增加数值,一个是减少数值,如果两个操作只做个一个,那么数据将不完整,出现异常(当然这种异常数据是不会报错的),但是添加了事务管理之后,就可以防止这种问题,事务的原子性:一件事情要么全做要么不做,一旦有操作失败,那么事务将进行rallback()回滚,撤销之前的所有事务操作。

  如下图:

    即使执行了语句,但是后面遇到了1/0的数值计算异常,那么 事务会进行回滚,撤销操作,数据库数据还是保持原样。事务一旦commit成功,再执行rollback回滚已经没有效果了。

测试代码:

public int updateUserInfo() {
        Session session = sessionFactory.getCurrentSession();
        String hql = "update UserEntity user set user.username='改1次' where user.id=1";
        session.createQuery(hql).executeUpdate();
        hql = "update UserEntity user set user.username='改2次' where user.id=1";
        session.createQuery(hql).executeUpdate();
        List<UserEntity> usersList = session.createQuery("from UserEntity ").list();
        for (UserEntity u:usersList){
            System.out.println(u.getUsername()+" : "+u.getCreateTime());
        }
        int i = 1/0;
        return 0;
    }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/d94447d92b5394097ec76eb2af13b4d4.html