事务隔离级别
.NET Core中的IDbConnection接口提供了BeginTransaction方法作为执行事务,BeginTransaction方法提供了两个重载,一个不需要参数BeginTransaction()默认事务隔离级别为RepeatableRead;另一个BeginTransaction(IsolationLevel il)可以根据业务需求来修改事务隔离级别。由于Dapper是对IDbConnection的扩展,所以Dapper在执行增删除改查时所有用到的事务需要由外部来定义。事务执行时与数据库之间的交互如下:
从WireShark抓取的数据包来看程序和数据交互步骤依次是:建立连接-->设置数据库隔离级别-->告诉数据库一个事务开始-->执行数据增删查改-->提交事务-->断开连接
准备工作
准备数据库:Mysql (笔者这里是:MySql 5.7.20 社区版)
创建数据库并创建数据表,创建数据表的脚本如下:
CREATE TABLE `posts` (
`Id` varchar(255) NOT NULL ,
`Text` longtext NOT NULL,
`CreationDate` datetime NOT NULL,
`LastChangeDate` datetime NOT NULL,
`Counter1` int(11) DEFAULT NULL,
`Counter2` int(11) DEFAULT NULL,
`Counter3` int(11) DEFAULT NULL,
`Counter4` int(11) DEFAULT NULL,
`Counter5` int(11) DEFAULT NULL,
`Counter6` int(11) DEFAULT NULL,
`Counter7` int(11) DEFAULT NULL,
`Counter8` int(11) DEFAULT NULL,
`Counter9` int(11) DEFAULT NULL,
PRIMARY KEY (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
创建.NET Core Domain类:
[Table("Posts")]
public class Post
{
[Key]
public string Id { get; set; }
public string Text { get; set; }
public DateTime CreationDate { get; set; }
public DateTime LastChangeDate { get; set; }
public int? Counter1 { get; set; }
public int? Counter2 { get; set; }
public int? Counter3 { get; set; }
public int? Counter4 { get; set; }
public int? Counter5 { get; set; }
public int? Counter6 { get; set; }
public int? Counter7 { get; set; }
public int? Counter8 { get; set; }
public int? Counter9 { get; set; }
}
具体怎样使用Dapper,请看上篇。
Read uncommitted 读未提交
允许脏读,即不发布共享锁,也不接受独占锁。意思是:事务A可以读取事务B未提交的数据。
优点:查询速度快
缺点:容易造成脏读,如果事务A在中途回滚
以下为执行脏读的测试代码片断:
public static void RunDirtyRead(IsolationLevel transaction1Level,IsolationLevel transaction2Level)
{
var id = Guid.NewGuid().ToString();
using (var connection1 = new MySqlConnection(connStr))
{
connection1.Open();
Console.WriteLine("transaction1 {0} Start",transaction1Level);
var transaction1 = connection1.BeginTransaction(transaction1Level);
Console.WriteLine("transaction1 插入数据 Start");
var sql = "insert into posts (id,text,CreationDate,LastChangeDate) values(@Id,@Text,@CreationDate,@LastChangeDate)";
var detail1 = connection1.Execute(sql,
new Post
{
Id &#