摘要:分享牛,数据库隔离级别,mysql事物,jdbc事物。事物开启命令,事物隔离级别。事物脏读、虚读、不可重复读。分布式事物。
首先我们查看下mysql的隔离级别,mysql的隔离级别命令如下所示:
可以看出,mysql的隔离级别是REPEATABLE READ。
CREATE TABLE accout(id INT PRIMARY KEY,NAME VARCHAR(100),money FLOAT) ;
INSERT INTO accout VALUES(1,'shareniu1',100);
INSERT INTO accout VALUES(2,'shareniu2',200);
INSERT INTO accout VALUES(3,'shareniu3',300);
开启事物之前 我们首先要开启隔离级别。好比去买东西,先那点钱再去买东西,万一没拿钱去买东西,还要重新拿钱。
下面我们开启两个窗口,连接到mysql数据库,两个连接,代表的a、b两个线程,我们在a中开启不同隔离级别的事物,在b中,不同的命令操作,看b是否对a事物的结果产生影响。
这里需要注意,开启事物之前,先设置事物的隔离级别,不然,事物开启,无法在设置事物隔离级别。
a开启事物,b不开启事物也就是使用默认的隔离界别。分别打开命令窗口如下所示:
命令如下:
在a中开始设置事物隔离级别的命令
set transaction isolation level READ UNCOMMITTED
start transaction;
SELECT * FROM accout WHERE id=3;
a查询完毕 b开始执行。
在b中,进行更新sql,命令如下:
UPDATE accout SET money=money+100 WHERE id=3;
再次在a中执行SELECT * FROM accout WHERE id=3;
发现,数据不一致了,如下图所示:
说明开启这种隔离级别,其他的事物会影响这个事物,上面的情况典型的出现了,不可重复读。
下面继续在a中执行如下sql.
SELECT * FROM accout ;执行完毕之后,再次在b中执行插入sql如下:
INSERT INTO accout VALUES(4,'shareniu4',400);
再次在a中执行查询sql如下所示:
SELECT * FROM accout ;
发现数据跟第一次查询的不一致,其他事物的插入操作,影响了当前事物的查询结果。这种例子是典型的出现了虚读。也是错误的,程序的完整如下图所示:
上面的2中情况,是b没有开启事物,如果b开启事物呢?是否会对a产生影响呢?我们在b中设置事物的隔离级别,开启事物,看下是否对a程序有影响。
在b中执行如下命令:
set transaction isolation level READ UNCOMMITTED
start transaction;
然后在a中执行查询命令如下:
SELECT * FROM accout ;
然后我们在b中插入一条数据。sql如下:
INSERT INTO accout VALUES(6,'shareniu6',600);
再次在a中执行上面的sql查询语句:
SELECT * FROM accout ;
发现了数据不一致,所以这个就是典型的脏读问题。如下图所示:
mysql事物隔离级别的设置,其他的可以根据这个例子进行自行测试。下面我们总结一下我测试的结果:
1.MySQL:默认REPEATABLE READ ORACLE:默认READ COMMITTED。
以下情况(是错的)
l 脏读:一个线程中的事务读到了另外一个线程中未提交的数据。
l 不可重复读:一个线程中的事务读到了另外一个线程中已经提交的update的数据。
l 虚读:一个线程中的事务读到了另外一个线程中已经提交的insert的数据。
要想避免以上现象,通过更改事务的隔离级别来避免:
l READ UNCOMMITTED 脏读、不可重复读、虚读有可能发生。
l READ COMMITTED 避免脏读的发生,不可重复读、虚读有可能发生。
l REPEATABLE READ 避免脏读、不可重复读的发生,虚读有可能发生。
l SERIALIZABLE 避免脏读、不可重复读、虚读的发生。
事物的隔离级别是只跟当前的事物隔离级别有关,与其他的线程事物无关。
从上到下,隔离级别越高,就性能越差。
分享牛原创(尊重原创 转载对的时候第一行请注明,转载出处来自分享牛http://blog.csdn.net/qq_30739519)