事务的4大特性(ACID):
原子性(Atomicity):事务是数据库的逻辑工作单位,它对数据库的修改要么全部执行,要么全部不执行,通俗点就是开启了一个事物,那么这个事物内的所有操作(增删改sql),只有事物提交了,这些操作对数据库中的数据才起作用。
一致性(Consistemcy):事务前后,数据库的状态都满足所有的完整性约束,通俗点就是如果事物提交后得到的结果是一样的,那么事物中间不论有多少操作(多少个增删改),事物保证我们最终要的结果是一样的。
隔离性(Isolation):并发执行的N个事务是隔离的,一个不影响一个,一个事务在没有commit之前,被修改的数据不可能被其他事务看到(通过设置数据库的隔离级别)。
持久性(Durability):持久性意味着当系统或介质发生故障时,确保已提交事务的更新不能丢失。持久性主要在于DBMS的恢复性能。
那么事物的隔离性可能导致一下问题的发生:
1,脏读
脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。
2,不可重复读
不可重复读是指在对于数据库中的某个数据,一个事务范围内多次查询却返回了不同的数据值,这是由于在查询间隔,被另一个事务修改并提交了。
3,虚读(幻读)
幻读是事务非独立执行时发生的一种现象。例如事务T1对一个表中所有的行的某个数据项做了从“1”修改为“2”的操作,这时事务T2又对这个表中插入了一行数据项,而这个数据项的数值还是为“1”并且提交给数据库。而操作事务T1的用户如果再查看刚刚修改的数据,会发现还有一行没有修改,其实这行是从事务T2中添加的,就好像产生幻觉一样,这就是发生了幻读。
幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
那么怎么解决这些问题呢,我们可以通过给数据库设置隔离级别来有效的解决这些问题
现在来看看MySQL数据库为我们提供的四种隔离级别:
① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
② Repeatable read (可重复读):可避免脏读、不可重复读的发生。
③ Read committed (读已提交):可避免脏读的发生。
④ Read uncommitted (读未提交):最低级别,任何情况都无法保证。
mysql查看事物隔离级别的sql: select @@tx_isolation;
mysql设置隔离级别的sql:set tx_isolation='事物隔离级别名称';
当然也可以通过jdbc来设置:如果是使用JDBC对数据库的事务设置隔离级别的话,也应该是在调用Connection对象的setAutoCommit(false)方法之前。
调用Connection对象的setTransactionIsolation(level)即可设置当前链接的隔离级别
注:隔离级别越高,执行效率越差;数据库避免脏读的做法是通过锁表来实现的。