mysql事务隔离级别测试

其中sleep是为了模拟web环境的慢速操作。上述代码需要同时执行两个进程

上面是测试代码,这段代码的本意是,如果找到name=1的那条数据,那么就不再插入。mysql事务隔离有四个级别

1.READ UNCOMMITTED-读未提交

2.READ COMMITTE-读已提交

3.REPEATABLE READ -可重复读

4.SERIALIZABLE -串行

经过测试第一种和第四种即READ UNCOMMITED和SERIALIZABLE满足需求,其他级别下均会重复插入。

第一种情况,手册里说它是“脏读”。实验中发现它可以读取别的事务还没有提交的数据。如果第一个事务提交失败,那么整个业务不管同时被请求多少次,都会执行失败。因为第二个事务已经读取了第一个事务的“脏数据”,所以,它不会再去执行插入的操作,而如果第一个事务执行失败,则整个业务等于没有被执行。当然它也会造成在同一事务内读取的同一条数据不同的问题。

 

第二种,一直没弄明白,如果谁弄的很清楚了,请告诉我一声。

 

第三种,可重复读取,意思是在同一事务中两次读取同一条数据的结果是一样的。当然,在别的进程读取的也是原先的未被修改的数据。这是mysql默认的事务隔离级别。如果在这种级别下并发2个或者多个进程执行上述代码,不管有没有开启事务,读取的都是未提交之前的数据。

 

第四种,串行。我测试的结果是,如果同时两个进程执行上面的代码的话,第二个执行的必须等待,也就是在第一个进程没有完成之前,第二个进程不能读取,更别说操作了。但是,如果没有开启事务,则可以读取,但是读取的还是提交之前的数据。

 

最后附上事务的特性,和一些相关的问题。

事务的基本特性


l Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成功,要么全部失败。

l Consistency(一致性):只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。

l Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。

l Durability(持久性):事务结束后,事务处理的结果必须能够得到固化。


共享数据库可能出现的问题
l 更新丢失(Lost update):两个事务都同时更新一行数据,但是第二个事务却中途失败退出,导致对数据的两个修改都失效了。这是因为系统没有执行任何的锁操作,因此并发事务并没有被隔离开来。

l 脏读取(Dirty Reads):一个事务开始读取了某行数据,但是另外一个事务已经更新了此数据但没有能够及时提交。这是相当危险的,因为很可能所有的操作都被回滚。

l 不可重复读取(Non-repeatable Reads):一个事务对同一行数据重复读取两次,但是却得到了不同的结果。例如,在两次读取的中途,有另外一个事务对该行数据进行了修改,并提交。

l 两次更新问题(Second lost updates problem):无法重复读取的特例。有两个并发事务同时读取同一行数据,然后其中一个对它进行修改提交,而另一个也进行了修改提交。这就会造成第一次写操作失效。

l 虚读(Phantom Reads):事务在操作过程中进行两次查询,第二次查询的结果包含了第一次查询中未出现的数据(这里并不要求两次查询的SQL语句相同)。这是因为在两次查询过程中有另外一个事务插入数据造成的。

 

|加上我这种重复记录的情况,这种情况只有使用最后一种才可以完全避免,当然这会对数据库的性能产生极大影响。所以,需要具有比较完善的架构。

 

当然,我觉得这既是值得的,也是可行的。在大部分的读取中,都可以读取缓存,当然事务中的读取除外。而把大部分的数据库都用来写。

数据库应该只作为一个存储的地方,而不应该还有过多的业务逻辑,因为始终sql这种是无法面向最终用户的,一般情况下,数据只有在程序的解释下才能有正确的含义。

 

 

发布了17 篇原创文章 · 获赞 1 · 访问量 5万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览