Spring事务的实现是通过SpringAop来拦截需要事务的方法,通过aop拦截出现异常的方法。以及配合动态代理去执行。

数据库的隔离级别

我们来看下事务与数据库的隔离级别的,关系
数据库的隔离级别分为:

  • Read Uncommitted
  • Read Commit
  • Repeatable Read
  • Serializable

这四类隔离级别会导致数据库数据的读取问题:分为脏读,不可重复度,幻读。

  • 脏读:一个事物a读到了另一个事务b未提交的数据,则b回滚后,a读取的数据无效;
  • 不可重复读:一个事务a第二次读到了另一个事务b修改的数据(a事务首先读到数据,事务还未提交,事务b修改了a读到的数据并提交,事务a读到的两次数据不一致);
  • 幻读:在统计数据的事务a两次统计的数据不一致(因为有其他事务新增数据)
  • 第一类丢失更新:a事务回滚覆盖了b事务提交的数据;
  • 第二类丢失更新:a事务覆盖了b事务提交的数据.
    在上面的解释中,可以看出不可重复读和幻读的解释很相似,都是两次读到的数据不一致。我们来说说不可重复读和幻读的区别
    不可重复读和幻读
    如果使用锁机制来实现这两种隔离级别,在可重复读中,该sql第一次读取到数据后,就将这些数据加锁,其它事务无法修改这些数据,就可以实现可重复 读了。但这种方法却无法锁住insert的数据,所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert数据提交,这时事务A就会 发现莫名其妙多了一条之前没有的数据,这就是幻读,不能通过行锁来避免。需要Serializable隔离级别 ,读用读锁,写用写锁,读锁和写锁互斥,这么做可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。
    所以说不可重复读和幻读最大的区别,就在于如何通过锁机制来解决他们产生的问题。总结一下就是
    幻读的重点在于新增或者删除
    不可重复读的重点是修改

    经常使用的mysql数据库是可重复读,避免了脏读和不可重复读,但是还是有幻读问题的存在,因为幻读需要加上表级别的锁。