事物的介绍

1、事物简介

        事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transactionend transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

2、为什么要事物

事务是为解决数据安全操作提出的,事务控制实际上就是控制数据的安全访问。

         用一个简单例子说明:银行转帐业务,账户A要将自己账户上的1000元转到B账户下面,A账户余额首先要减去1000元,然后B账户要增加1000元。假如在中间网络出现了问题,A账户减去1000元已经结束,B因为网络中断而操作失败,那么整个业务失败,必须做出控制,要求A账户转帐业务撤销。这才能保证业务的正确性,完成这个操走就需要事务,将A账户资金减少和B账户资金增加放到同一个事务里,要么全部执行成功,要么全部撤销,这样就保证了数据的安全性。

         在jdbc api中,默认的情况为自动提交事务,也就是说,每一条对数据库的更新的sql语句代表一项事务,操作成功后,系统自动调用commit()来提交,否则将调用rollback()来撤消事务。

        在jdbc api中,可以通过调用setAutoCommit(false) 来禁止自动提交事务。然后就可以把多条更新数据库的sql语句做为一个事务,在所有操作完成之后,调用commit()来进行整体提交。倘若其中一项 sql操作失败,就不会执行commit()方法,而是产生相应的sqlexception,此时就可以捕获异常代码块中调用rollback()方法撤消事务。

 3、事物的ACID特性

  • 原子性(atomicity):指整个事务是不可以分割的工作单元。只有事务中所有的操作执行成功,才算整个事务成功,事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该回到执行事务前的状态。
  • 一致性(consistency):数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对于银行转账事务,不管事务成功还是失败,应该保证事务结束后两个转账账户的存款总额是与转账前一致的。
  • 隔离性(isolation):指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。
  • 持久性(durability):指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

4、Java 中有几种事物类型?

  1. JDBC事物
  2. JTA(Java Transaction API)事务
  3. Spring容器事务

①JDBC事物

  • 在JDBC中处理事务,都是通过Connection完成的。同一事务中所有的操作,都在使用同一个Connection对象。JDBC事务默认是开启的,并且是默认提交。

  • JDBC Connection 接口提供了两种事务模式:自动提交手工提交

  • 在connection类中提供了3个控制事务的方法:

    (1) setAutoCommit(Boolean autoCommit):设置是否自动提交事务;

    (2) commit();提交事务;

    (3) rollback();撤消事务;

  • 传统JDBC操作流程:

      1).获取JDBC连接   2).声明SQL   3).预编译SQL   4).执行SQL   5).处理结果集   

      6).释放结果集  7).释放Statement  8).提交事务  9).处理异常并回滚事务 10).释放JDBC连接

  • JDBC优缺点:1.冗长、重复     2.显示事务控制     3.每个步骤不可获取    4.显示处理受检查异常

  • JDBC为使用Java进行数据库的事务操作提供了最基本的支持。通过JDBC事务,我们可以将多个SQL语句放到同一个事务中,保证其ACID特性。JDBC事务的主要优点就是API比较简单,可以实现最基本的事务操作,性能也相对较好。但是,JDBC事务有一个局限:一个 JDBC 事务不能跨越多个数据库!所以,如果涉及到多数据库的操作或者分布式场景,JDBC事务就无能为力了。

JDBC中四种隔离:

  • 读未提交(Read uncommitted):这种事务隔离级别下,select语句不加锁。此时,可能读取到不一致的数据,即“读脏 ”。这是并发最高,一致性最差的隔离级别。
  • 读已提交(Read committed):可以读取到已经提交的内容,可避免 脏读 的发生。
  • 可重复读(Repeatable read):MySql默认隔离级别。可避免 脏读 、不可重复读 的发生。
  • 串行化(Serializable ):可避免 脏读、不可重复读、幻读 的发生。

     ***目前几乎没有数据库实现了所有隔离级别

②JTA(Java Transaction API)事务 

  • JTA(Java Transaction API)提供了跨数据库连接(或其他JTA资源)的事务管理能力。JTA事务管理则由JTA容器实现,J2ee框架中事务管理器与应用程序,资源管理器,以及应用服务器之间的事务通讯。

③Spring容器事务

  • 事务管理器接口PlatformTransactionManager通过getTransaction(TransactionDefinition definition)方法来得到事务,这个方法里面的参数是TransactionDefinition类,这个类就定义了一些基本的事务属性。
  • 事务属性包含了5个方面:

  1. 传播行为
  2. 隔离规则
  3. 回滚规则
  4. 事务超时
  5. 是否只读

public interface TransactionDefinition {
    int getPropagationBehavior(); // 返回事务的传播行为
    int getIsolationLevel(); // 返回事务的隔离级别,事务管理器根据它来控制另外一个事务可以看到本事务内的哪些数据
    int getTimeout();  // 返回事务必须在多少秒内完成
    boolean isReadOnly(); // 事务是否只读,事务管理器能够根据这个返回值进行优化,确保事务是只读的
}

7种传播行为:

  • PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。  默认方式
  • PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
  • PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
  •  PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
  • PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
  • PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
  • PROPAGATION_NESTED--如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。

五个隔离级别:

  • ISOLATION_DEFAULT:这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别。
  • ISOLATION_READ_UNCOMMITTED:这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据(select语句不加锁)。这是并发最高,一致性最差的隔离级别

 现象:这种隔离级别会产生脏读,不可重复读和幻像读。

  • ISOLATION_READ_COMMITTED:保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。

 现象:这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。

  • ISOLATION_REPEATABLE_READ:这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
  • ISOLATION_SERIALIZABLE:这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

现象:除了防止脏读,不可重复读外,还避免了幻像读。

事务的属性可同通过注解方式或配置文件配置:

注解方式:

  • @Transactional只能被应用到public方法上,对于其它非public的方法,如果标记了@Transactional也不会报错,但方法没有事务功能.
//该类中所有方法具有事务性
@Transactional
public class StudentServiceImpl implements StudentService {}:

//本方法采用这种事务
@Transactional(rollbackFor = FileNotFoundException.class)
public int update(Student student) throws FileNotFoundException {}:
  • spring 自动托管事务: 默认只检测运行时异常
异常:提供 程序出现例外情况,通过妥善处理,让程序能够执行下去的 一种机制
  运行时异常:非受检查异常  由于程序人员考虑不周密,出现的例外情况
  编译时异常:受检查异常    提醒检查程序
  • 默认情况下,一个有事务方法, 遇到RuntimeException 时会回滚 . 遇到 受检查的异常 是不会回滚 的. 要想所有异常都回滚,要加上 @Transactional( rollbackFor={Exception.class,其它异常}) 

@Transactional(
    readOnly = false, //读写事务
    timeout = -1 ,     //事务的超时时间,-1为无限制
    noRollbackFor = ArithmeticException.class, //遇到指定的异常不回滚
    isolation = Isolation.DEFAULT, //事务的隔离级别,此处使用后端数据库的默认隔离级别
    propagation = Propagation.REQUIRED //事务的传播行为

)

配置文件(aop拦截器方式):


<tx:advice id="advice" transaction-manager="txManager">
          <tx:attributes>
            <!-- tx:method的属性:
                * name 是必须的,表示与事务属性关联的方法名(业务方法名),对切入点进行细化。通配符 
                     (*)可以用来指定一批关联到相同的事务属性的方法。
                      如:'get*'、'handle*'、'on*Event'等等.
                * propagation:不是必须的,默认值是REQUIRED表示事务传播行为,
                  包括REQUIRED,SUPPORTS,MANDATORY,REQUIRES_NEW,NOT_SUPPORTED,NEVER,NESTED
                * isolation:不是必须的 默认值DEFAULT ,表示事务隔离级别(数据库的隔离级别)
                * timeout:不是必须的 默认值-1(永不超时),表示事务超时的时间(以秒为单位)
                * read-only:不是必须的 默认值false不是只读的表示事务是否只读?
                * rollback-for: 不是必须的表示将被触发进行回滚的 Exception(s);以逗号分开。
                   如:'com.foo.MyBusinessException,ServletException'
                * no-rollback-for:不是必须的表示不被触发进行回滚的 Exception(s),以逗号分开。                                        
                   如:'com.foo.MyBusinessException,ServletException'   
                任何 RuntimeException 将触发事务回滚,但是任何 checked Exception 将不触发事务回滚                     
            -->
             <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
             <tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"/>
             <tx:method name="delete*" propagation="REQUIRED" isolation="DEFAULT" read-only="false"  rollback-for="Exception"/>
             <!-- 其他的方法之只读的 -->
             <tx:method name="*" read-only="true"/>
          </tx:attributes>

————————————————
版权声明:本文为优快云博主「share_happy_life」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_37934748/article/details/82774230

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值