事务及隔离级别

1.为什么使用事务?

     为了保证数据的完整性和一致性,对数据操作要保证数据的安全

 

2.什么是事务?

     将一组操作数据的SQL作为一个整体提交,要么都执行,要么都不执行

 

3..事务的特性

  • 原子性
    • 将多条sql语句作为一个整体,不可分割
  • 一致性
    • 数据操作前后,整体保持一致
      • 例如转账,一方钱少,另一方钱多,保持平衡,总额不变
  • 隔离性
    • 多个事务并发操作同一数据时,保证事务时隔离开的,相互不会受到干扰,保证数据安全
  • 持久性
    • 事务操作数据的结果永久的保存到持久化存储器

 

4..事务的隔离级别设置

  • 通过Connection接口的方法设置事务级别

void setTransactionIsolation(int level) throws SQLException

 

5.事务隔离级别

  • 未提交读       1    
    • int TRANSACTION_READ_UNCOMMITTED=1   
  • 已提交读       2
    • int TRANSACTION_READ_COMMITTED=2
  • 重复读          4
    • int TRANSACTION_REPEATABLE_READ=4
  • 序列化/不可并发        8
    • int TRANSACTION_SERIALIZABLE=8

 

6.数据默认的隔离级别

          Mysql    4

          oracle    2

 

7.每个隔离能解决的问题

  • 不适用事务会出现的问题
    • 数据丢失,脏读,不可重复读,幻读
  • 使用事务隔离级别后,每个隔离界别能解决的问题

 

事务隔离级别

数据丢失

脏读

不可重复读

幻读

TRANSACTION_READ_UNCOMMITTED(1)

解决

未解决

未解决

未解决

TRANSACTION_READ_COMMITTED(2)

解决

解决

未解决

未解决

TRANSACTION_REPEATABLE_READ(4)

解决

解决

解决

未解决

TRANSACTION_SERIALIZABLE(8)

解决

解决

解决

解决

 

8.每个级别的含义和作用

  • 未提交读
    • 一个事务读取到了另一个事务还没有提交事务的数据
  • 已提交读
    • 一个事务读取到了另一个事务已经提交事务的数据
  • 重复读
    • 一个事务只能重复读取当前事务的操作数据,而不能读取到别的事务未提交或已提交的数据
  • 序列化/不可并发
    • 解决了所有问题
    • 幻读
      • 一个事务正在进行某种统计,其它事务又进行数据的添加,删除或修改等操作,导致两次事务的统计结果不一致,就产生了幻读
    • Select * from xxx where id < 5 for update //行级锁

 

9.事务管理方式

     编程式事务

 

使用原生的JDBC API进行事务管理

[1]获取数据库连接Connection对象

[2]取消事务的自动提交

[3]执行操作

[4]正常完成操作时手动提交事务

[5]执行失败时回滚事务

[6]关闭相关资源

 

Connection con = .... ;

try{

con.setTransactionIsolation(4);

con.setAutoCommit(false); //开启事务

//执行一条或多条SQL

con.commit(); //提交事务

} catch(Exception e){

con.rollback(); //回滚事务

} finally{

con.close();

}

 

     声明式事务

          通过相关配置,给程序增加事务操作

          Spring为了管理底层的事务,提供了PlatformTransactionManager接口,并提供了相关实现类

               DataSourceTransactionManager          Spring与JdbcTemplate框架集成时,提供事务管理

               HibernateTransanctionManager          Spring与Hibernate框架集成时,提供的事务管理

 

 

10.声明式事务使用

 

1) 了解需求

2) 创建表结构

3)  搭建环境

 

          ①导包

com.springsource.net.sf.cglib-2.2.0.jar

com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

commons-logging-1.1.3.jar

spring-aop-4.0.0.RELEASE.jar

spring-aspects-4.0.0.RELEASE.jar

spring-beans-4.0.0.RELEASE.jar

spring-context-4.0.0.RELEASE.jar

spring-core-4.0.0.RELEASE.jar

spring-expression-4.0.0.RELEASE.jar

spring-jdbc-4.0.0.RELEASE.jar

spring-orm-4.0.0.RELEASE.jar

spring-tx-4.0.0.RELEASE.jar

mysql-connector-java-5.1.7-bin.jar

c3p0-0.9.1.2.jar

 

          ②创建beans.xml

    • 引用外部资源文件:jdbc.properties

<!-- 加载外部属性资源文件 -->

<context:property-placeholder location="classpath:/jdbc.priperties"/>

 

    • 声明c3p0

<!-- 声明c3p0数据源对象 -->

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

     <property name="user" value="${jdbc.username}"></property>

     <property name="password" value="${jdbc.password}"></property>

     <property name="jdbcUrl" value="${jdbc.url}"></property>

     <property name="driverClass" value="${jdbc.driverClass}"></property>

     <property name="initialPoolSize" value="2"></property>

     <property name="minPoolSize" value="5"></property>

     <property name="maxPoolSize" value="20"></property>

</bean>

 

    • 声明JdbcTemplate

<!-- 声明jdbcTemplate对象 -->

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">

     <property name="dataSource" ref="dataSource"></property>

</bean>

 

         

          ③测试c3p0

          

          ④创建Dao接口和实现类

 

          ⑤创建Service接口和实现类

 

          ⑥测试Service接口方法

                    无事务情况:可能出现数据不一致情况

                    有事务情况:采用Spring的声明式事务解决问题

                         [1]声明事务管理器对象

<!-- 事务管理器 -->

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

<property name="dataSource" ref="dataSource"/>

</bean>

 

                         [2]启用基于注解的声明式事务

<!-- 开启基于注解的声明式事务

transaction-manager="transactionManager" 默认值.

-->

<tx:annotation-driven transaction-manager="transactionManager"/>

 

          

11.事务属性

 

1)事务传播行为

          方法被调用时,事务的开启方式

          一共有7种传播方式:

               propagation=Propagation.REQUIRED    默认值

                    表示一个方法被调用时,如果已经存在事务,则加入这个事务,否则,开启一个新事物

               propagation=Propagation.REQUIRES_NEW 

                    表示一个方法被调用时,不管调用的方法有无事务,被调用的方法总会为自己开启一个新事物

2)事务隔离级别

          isolation=Isolation.DEFAULT   

                    表示与数据库的默认隔离级别一致

3)事务回滚策略

          框架默认的回滚策略不适合项目开发,希望有异常就回滚事务

               rollbackFor=Exception.class       设置遇到的指定类型进行事务回滚

               noRollbackFor      设置遇到指定的类型不进行回滚事务

4) 事务超时属性

          timeout=3      设置事务的超时时间,单位:s

5) 只读属性

          readOnly=true       

               一般查询数据时,需设置为true,数据库底层会对查询进行优化处理,提高效率

 

12.基于XML文件的声明式事务

<!-- 基于XML的声明式事务配置 -->

<aop:config>

<aop:pointcut expression="execution(* com.atguigu..service.*Service.*(..))" id="txPointcutId"/>

<aop:advisor advice-ref="adviceId" pointcut-ref="txPointcutId"/>

</aop:config>

 

 

<tx:advice id="adviceId" transaction-manager="transactionManager">

<tx:attributes>

<tx:method name="purchase"

propagation="REQUIRED"

isolation="DEFAULT"

rollback-for="java.lang.Exception"

timeout="3" />

<tx:method name="update*" propagation="REQUIRED"

isolation="DEFAULT"

rollback-for="java.lang.Exception"

timeout="3" />

<tx:method name="query*" read-only="true"/>

<tx:method name="get*" read-only="true"/>

<tx:method name="*" read-only="true"/>

</tx:attributes>

</tx:advice>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值