Net Core中数据库事务隔离详解——以Dapper和Mysql为例

事务隔离级别

.NET Core中的接口提供了方法作为执行事务,方法提供了两个重载,一个不需要参数默认事务隔离级别为;另一个可以根据业务需求来修改事务隔离级别。由于Dapper是对IDbConnection的扩展,所以Dapper在执行增删除改查时所有用到的事务需要由外部来定义。事务执行时与数据库之间的交互如下:

从WireShark抓取的数据包来看程序和数据交互步骤依次是:

准备工作

准备数据库:Mysql (笔者这里是:MySql 5.7.20 社区版)

创建数据库并创建数据表,创建数据表的脚本如下:

创建.NET Core Domain类:

具体怎样使用Dapper,请看上篇。

Read uncommitted 读未提交

允许脏读,即不发布共享锁,也不接受独占锁。意思是:事务A可以读取事务B未提交的数据。

优点:查询速度快

缺点:容易造成脏读,如果事务A在中途回滚

以下为执行脏读的测试代码片断:

1、当执行,即事务1和事务2都设置为时结果如下:

当事务1回滚以后,数据库并没有事务1添加的数据,所以事务2获取的数据是脏数据。

2、当执行,即事务1隔离级别为,事务2的隔离级别设置为,结果如下:

3、当执行,即事务1隔离级别为,事务2的隔离级别为,结果如下:

结论:当事务2(即取数据事务)隔离级别设置为,那么不管事务1隔离级别为哪一种,事务2都能将事务1未提交的数据得到;但是测试结果可以看出当事务2为则获取不到事务1未提交的数据从而导致程序异常。

Read committed 读取提交内容

这是大多数数据库默认的隔离级别,但是,不是MySQL的默认隔离级别。读取数据时保持共享锁,以避免脏读,但是在事务结束前可以更改数据。

优点:解决了脏读的问题

缺点:一个事务未结束被另一个事务把数据修改后导致两次请求的数据不一致

测试重复读代码片断:

在事务1中detail1中得到的Counter1为1,事务2中将Counter1的值修改为2,事务1中detail2得到的Counter1的值也会变为2

下面分几种情况来测试:

1、当事务1和事务2都为时,结果如下:

2、当事务1和事务2隔离级别都为时,执行结果如下:

3、当事务1隔离级别为,事务2隔离级别为时执行结果如下:

4、当事务1隔离级别为,事务2隔离级别为时执行结果如下:

结论:当事务1隔离级别为时数据可重复读,当事务1隔离级别为时可以不可重复读,不管事务2隔离级别为哪一种不受影响。

注:在RepeatableRead隔离级别下虽然事务1两次获取的数据一致,但是事务2已经是将数据库中的数据进行了修改,如果事务1对该条数据进行修改则会对事务2的数据进行覆盖。

Repeatable read (可重读)

这是MySQL默认的隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行(目标数据行不会被修改)。

优点:解决了不可重复读和脏读问题

缺点:幻读

测试幻读代码

分别对几种情况进行测试:

1、事务1和事务2隔离级别都为,结果如下:

2、事务1和事务2隔离级别都为,结果如下:

3、当事务1的隔离级别为,事务2的隔离级别为时,执行结果如下:

4、当事务1的隔离级别为,事务2的隔离级别为时,执行结果如下:

结论:当事务隔离级别为时虽然两次获取数据条数相同,但是事务2是正常将数据插入到数据库当中的。当事务1隔离级别为程序异常,原因接下来将会讲到。

Serializable 序列化

这是最高的事务隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。

优点:解决幻读

缺点:在每个读的数据行上都加了共享锁,可能导致大量的超时和锁竞争

当执行或执行时代码都会报异常,是因为隔离级别下强制事务以串行方式执行,由于这里是一个主线程上第一个事务未完时执行了第二个事务,但是第二个事务必须等到第一个事务执行完成后才参执行,所以就会导致程序报超时异常。这里将代码作如下修改:

执行结果如下:

结论:当事务1隔离级别为时对后面的事务的增删改改操作进行强制排序。避免数据出错造成不必要的麻烦。

注:在.NET Core中枚举值中还提供了另外三种隔离级别:、、由于这种事务隔离级别MySql不支持设置时会报异常:

总结

本节通过Dapper对MySql中事务的四种隔离级别下进行测试,并且指出事务之间的相互关系和问题以供大家参考。

1、事务1隔离级别为时,可以读取其它任何事务隔离级别下未提交的数据

2、事务1隔离级别为时,不可以读取其它事务未提交的数据,但是允许其它事务对数据表进行查询、添加、修改和删除;并且可以将其它事务增删改重新获取出来。

3、事务1隔离级别为时,不可以读取其它事务未提交的数据,但是允许其它事务对数据表进行查询、添加、修改和删除;但是其它事务的增删改不影响事务1的查询结果

4、事务1隔离级别为时,对其它事务对数据库的修改(增删改)强制串行处理。

原文地址:http://www.cnblogs.com/vipyoumay/p/8134434.html

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171231B02WKB00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券