事务四大特性
1.原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到事务执行之前的状态
2.一致性:如果在执行事务之前数据库是一致性的,那么在执行事务后数据库也还是一致的
3.隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事物会撤回。事务的100%隔离,需要牺牲速度
4.持久性:事务一旦提交,其结果就是永久的。即便发生系统故障,也能恢复。
事务隔离级别
未提交读(Read Uncommitted):允许脏读,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。也就是可能读取到其他会话中未提交事务修改的数据
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认的都是该级别(不重复读)
可重复读(Repeated Read):可重复读。无论其他事务是否修改并提交了数据,在这个数据中看到的数据值始终不受其他事务影响。
串行读(Serializable):完全串行话的读。每次读都需要获得表级共享锁,读写相互都会阻塞
MySQL数据库(InnoDB引擎)默认使用可重复读(Repeated Read)
脏读、幻读、不可重复读
脏读:是指事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。
不可重复度:是指在数据库访问时,一个事务范围内的俩次相同查询却返回了不同数据。在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事物也该访问同一数据。那么在第一个事务中的俩次读数据之间,由于第二个事务的修改,第一个事务俩次读到的数据可能是不一样的。这样在一个事务内俩次读到的数据是不一样的,因此称为是不可重复读。
幻读:是指事务不是独立执行时发生的一种现象,比如第一个事务对第一个表中的数据进行了修改,这种修改涉及到表中的全部数据行,同时,第二个事务也修改这个表中的数据,这种修改是像表中插入一行新数据。那么就会发生,操作第一个事务的用户发现表中还没有修改的数据,就好像发生了幻觉一样。
不可重复度和幻读的区别:
如果使用锁机制来实现这俩种隔离级别,可在重复度中,该sql第一次读取到数据后,就将这些数据加锁,其他事务无法修改这些数据,就可以实现可重复读了。但这种方法却无法锁住insert的数据。所以当事务A先前读取了数据,或者修改了全部数据,事务B还是可以insert提交数据,这是事务A就会大仙莫名其妙的多了一条数据,这就是幻读,不能通过行锁来避免。所以需要串行读(Serializable)隔离级别,读用读锁,写用写锁,读锁和写锁互斥,这么做就可以有效的避免幻读、不可重复读、脏读等问题,但会极大的降低数据库的并发能力。
不可重复读重点在于update和delete,而幻读重点在于insert。如何通过锁机制来解决他们产生的问题。