spring第三部分(四)&.spring事务管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_39128354/article/details/81457773

Spring的事务管理

事务概念

一:.什么是事务

一组操作呀,要么都成功,有一个失败所有都失败。
事务是一系列的动作,一旦其中有一个动作出现错误,必须全部回滚,系统将事务中对数据库的所有已完成的操作全部撤消,滚回到事务开始的状态,
避免出现由于数据不一致而导致的接下来一系列的错误。事务的出现是为了确保数据的完整性和一致性,在目前企业级应用开发中,事务管理是必不可少的。

二:.事务的特性

1.原子性(Atomicity)事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。

2.一致性(Consistency)事务在完成时,必须是所有的数据都保持一致状态。

3.隔离性(Isolation)并发事务执行之间无影响,在一个事务内部的操作对其他事务是不产生影响,这需要事务隔离级别来指定隔离性。

4.持久性(Durability)一旦事务完成,数据库的改变必须是持久化的。

三:不考虑隔离性产生读问题

在企业级应用中,多用户访问数据库是常见的场景,这就是所谓的事务的并发。事务并发所可能存在的问题:
1.脏读:一个事务读到另一个事务未提交的更新数据。
2.不可重复读:一个事务两次读同一行数据,可是这两次读到的数据不一样。
3.幻读:一个事务执行两次查询,但第二次查询比第一次查询多出了一些数据行。
4.丢失更新:撤消一个事务时,把其它事务已提交的更新的数据覆盖了。

四:解决读问题

(1)设置隔离级别

Spring事务管理api

1spring事务管理俩种方式
第一种:编程式(事务管理)
第二种:声明式事务管理
(1)基于xml配置文件实现
(2)基于注解实现
2.spring事务管理的api介绍
接口

PlatformTransactionManager
    事务管理器
    (1)spring针对不同的dao层框架,提供接口不同的实现类
    事务                                      说明
    org.springframeworkjdbc.datasource.DataSource   使用springJDBC或IBatista进行持久化数据时使用
    TransactionManager
    org.springframework.orm.hibernate5.Hibernate        使用hibernate5进行持久化数据时使用
    TransactionManager

    搭建转账环境

    1.创建数据库表,添加数据
    id  username        salary
    1   小李          2000
    2   小马          1500
    2.创建service和dao类,实现注入关系
    配置文件
    <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 http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
        >
    <!--配置c3po-->
            <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">    
            <!--配置属性-->
            <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/student_teacher"></property>
            <property name="user" value="root"></property>
            <property name="password" value="123"></property>
            </bean>

            <bean id="orderService" class="ZZQ_Service.OrderService">
                <property name="orderDao" ref="orderDao"></property>
            </bean>

            <bean id="orderDao"  class="ZZQ_Service.OrderDao">
                <property name="jdbcTemplate" ref="jdbcTemplate"></property>
            </bean>

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

</beans>

(1)servicve层又叫业务逻辑层

public class OrderService {

    private OrderDao orderDao;

    public void setOrderDao(OrderDao orderDao) {
        this.orderDao = orderDao;
    }
    /**
     * 调用dao的方法
     * 业务逻辑层没写业务
     */
    public void accountMoney() {
        orderDao.lsessMaoey();

        orderDao.moreMoney();
    }
}

(2)dao层,单纯对数据库操作层,在dao层不添加业务

public class OrderDao {
    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    /**
     * 做对数据库操作的方法,不写业务逻辑
     */
    //小王少的方法
    public void lsessMaoey() {
        String sql="update account set salary=salary-? where username=?";
        jdbcTemplate.update(sql, 1000,"小李");

    }
    //小马多钱的方法
    public void moreMoney() {
        String sql="update account set salary=salary+? where username=?";
        jdbcTemplate.update(sql, 1000,"小马");
    }
}

(3)测试代码

public class TestMethod {
    @Test
    public void testOrder() {
        ApplicationContext applicationContext=
                        new ClassPathXmlApplicationContext("bean.xml");
        OrderService orderService = (OrderService) applicationContext.getBean("orderService");
        orderService.accountMoney();
    }
}

3产生问题

(1)如果小王少了1000之后,出现异常,小马保护会多1000钱丢失了

4.解决

Spring事务的隔离级别

名称 值 解释
ISOLATION_DEFAULT -1 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应
ISOLATION_READ_UNCOMMITTED 1 这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。
ISOLATION_READ_COMMITTED 2 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。
ISOLATION_REPEATABLE_READ 4 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻读。
ISOLATION_SERIALIZABLE 8 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻读。
(1)添加事务解决,出现异常进行回滚操作

声明式事务管理(xml) 1.配置文件方式用aop原理配置

<!--第一步:配置事务管理器-->
            <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <!--注入DataSource-->
                <property name="dataSource" ref="dataSource"></property>
            </bean>

            <!--第二步:配置事务增强-->
            <tx:advice id="txadvice" transaction-manager="transactionManager">
                <!--做事务操作-->
                <tx:attributes>
                    <!--设置事务操作方法的匹配原则-->
                    <tx:method name="account*" propagation="REQUIRED"/>
                </tx:attributes>
            </tx:advice>
            <!--第二三步:配置切面-->
            <aop:config>
                <aop:pointcut expression="execution(* ZZQ_Service.OrderService.*(..))" id="pointcut1"/>
                <!--切面-->
                <aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"/>


            </aop:config>

声明式事务管理(注解)
第一步.配置事务管理器

<!--第一步:配置事务管理器-->
            <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                <!--注入DataSource-->
                <property name="dataSource" ref="dataSource"></property>
            </bean>

第二步 配置事务注解

<!--第二步开启事务注解-->
            <tx:annotation-driven transaction-manager="transactionManager"/>

第三步在要使用事务的方法所在类上面添加注解
@Transactional
public class OrderService {

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试