????????一组要么同时成功提交,要么同时失败回滚的sql语句,是数据库操作的一个执行单元。
? ? ? ? 1)原子性(Atomicity)
????????????????强调事务中的多个操作是一个整体:事务内所有操作是一个整体、最小执行单元,要么全部成功,要么全部失败。
? ? ? ? 2)一致性(Consistency)
????????????????强调事务中不会保存不一致的状态:从一个一致性状态转到另一个一致性状态,有一个失败,全部回滚。
? ? ? ? 3)隔离性(Isolation)
????????????????强调数据库事务中事务之间互相不可见:一个事务所做的修改在提交之前,其余的事务是不可见的,看不到事务的中间状态。
? ? ? ? 4)持久性(Durability)
????????????????强调数据库能永久保存数据库,一旦提交就不可撤销:事务提交,所有的修改都会永久保存到数据库。
????????????????事务A读取了事务B尚未提交的数据。如果此时事务B由于失败导致数据回滚,那么事务A读取的数据就是脏数据。
????????????????
????????????????事务A读取了事务B提交的数据。事务A查询时,事务B查询并修改了同一条数据并提交,事务A再次读取到事务B修改后的数据,发现两次读取数据不一致,系统读取不到重复的数据,成为不可重复读。
????????????????
事务A读取了事务B新增或删除的数据,导致总数量不一致。事务A查询时,事务B新增了数据并提交,事务A再次查询时发现数据总量多了几条,就像产生了幻觉。
????????????????
????????????????脏读:读取了另一事务未提交的数据。
????????????????不可重复读:读取了另一事务提交了的更改数据,针对update。
????????????????幻读:读取了另一事务提交了的新增或删除数据,针对insert或delete。
????????数据库事务的隔离级别有4个,由低到高分别是Read uncommitted 、Read committed 、Repeatable read 、Serializable,级别越高,数据越安全,但性能越低。
????????分别可以解决脏读、不可重复读、幻读的问题。
????????
????????注意:Mysql中默认的隔离级别是:Repeatable read(可重复读)
????????REQUIRED?:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。
????????SUPPORTS?:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
????????MANDATORY?:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
????????REQUIRES_NEW?:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
????????NOT_SUPPORTED?:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
????????NEVER?:以非事务方式运行,如果当前存在事务,则抛出异常。
????????NESTED?:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于 REQUIRED。
????????@Transactional注解,既可以添加在方法上又可以添加在类上,当注解添加在类级别上,表示该类所有的公共方法都配置了相同的事务属性信息,
如果类级别和方法级别都配置了@Transactional,应用程序会优先以方法级别的事务属性来管理事务,换言之,方法级别的事务属性会覆盖类级别的事务属性。
????????建议:在业务层抛出异常,控制层统一处理。
????????????????java的访问权限主要有四种:private、default、protected、public,从左往右,权限依次变大;spring要求被代理的方法必须是public,其余权限spring不提供事务。
????????????????spring事务底层使用aop实现,jdk或cglib动态代理,如果使用final或static修饰了方法,在代理类里无法重写,无法实现事务。
????????????????同一个类中有事务A的方法A调用了有事务B的方法B,相当于直接使用this调用方法B,所以事务B不生效
????????解决方法
? ? ? ? ? ? ? ? a. 新加一个service
????????????????????????
? ? ? ? ? ? ? ? b.?在该service注入自己
????????????????????????
? ? ? ? ? ? ? ? c.?通过AopContent类
????????????????????????
使用spring的前提是,对象要被spring管理,如果service上不加@service注解,该类不由spring管理,事务自然不生效。
????????????????@Transactional(propagation = Propagation.NEVER),这种传播行为不支持事务,有事务会抛异常
????????????????主动捕捉了异常并处理,导致框架无法感知异常,无法回滚。
????????????????默认RuntimeException(运行时异常)和error(错误)回滚,Eexception(非运行时异常)就不回滚。
????????????????
????????????????实现只回归内部,不回滚外部,在内部手动捕捉异常-try...catch,并不继续往外抛。
????????????????????????