数据事务
MySql注意事项:
- MYSQL不支持创建表和删除表处理事务,原生事务也一样
- MyISAM 存储引擎不支持事务 需要改成 InnoDB
1.单库事务
- 单库事务是针一个db操作执行的事务,无论是 ISqlSugarClient和 SqlSugarClient 用法都一样
static void Main(string[] args)
{
var db = Sugar.GetInstance();
try
{
db.Ado.BeginTran();
db.Insertable(new Student() { Id = "1", Name ="hpf", SchoolId = 1 }).ExecuteCommand();
throw new Exception(); //手动抛出异常,回滚Sql
db.Ado.CommitTran();
}
catch (Exception ex)
{
db.Ado.RollbackTran();
}
Console.ReadLine();
}
- 如果一个db就一个库,那么你也可以用多租户事务节约代码,因为2者在一个库的情况下作用一样
db.BeginTran(); //去掉了.ado
db.CommitTran(); //去掉了.ado
db.RollbackTran(); //去掉了.ado
2.多租户事务(可跨库)
目前还没有学习多租户有关知识
3.调试事务
- db.ContextId从
事务开始、CURD、事务结束
必须一致 这个事务才会生效,如果是MYSQL也检查一下表引擎是否支持事务 - SqlsugarClient 可以用变量 var db=外部Db; 所有操作使用db保证一致
- SqlsuagrScope (该对象是线程安全对象,可以单例)可以用单例模式保证一致
项目运行起来的时候,在监视中手动输入 db.ContextId ,以便监控值是否保持不变
4.语法糖
特定语法,方便实用
4.1 语法糖一
这种适合全局异常,直接出错扔出并且回滚
这种方式我没测试过
using (var tran = db.UseTran())
{
//业务代码
//里面禁止写 try处理事务逻辑,格式一定按现在的风格来
tran.CommitTran();
}
//要写 try处理异常可以写在外面
4.2 语法糖二
这种适合没有异常处理的,减少了try 处理
static void Main(string[] args)
{
var db = Sugar.GetInstance();
var result = db.UseTran(() =>
{
db.Insertable(new Student() { Id = "2", Name = "hpf", SchoolId= 2 }).ExecuteCommand();
//throw new Exception(); //手动抛出异常,测试事务回滚功能
return true;
});
if (result.Data == false)
{
if (result.IsSuccess == false)
Console.WriteLine("事务提交失败");
}
else
Console.WriteLine("事务提交完成");
Console.ReadLine();
}
5.跨方法事务
目前还没有用到有关知识
6.CAP事务
目前还没有用到有关知识
7.异步事务
请不要在同步方法里面写下面方代码,必须是异步方法才行 返回是要带有Task async
7.1 用法一
static async Task Main(string[] args)
{
var db = Sugar.GetInstance();
try
{
db.BeginTran();
await db.Insertable(new Student() { StudentId=13, Name="qwe"}).ExecuteCommandAsync();
//throw new Exception(); //手动抛出异常,测试事务回滚功能
db.CommitTran();
}
catch (Exception)
{
db.RollbackTran();
}
Console.ReadLine();
}
7.2 用法二
注意:
await db.UseTranAsync 前面的await不要漏掉了
public class Program
{
static async Task Main(string[] args)
{
var db = Sugar.GetInstance();
await Test(db);
Console.ReadLine();
}
public static async Task Test(SqlSugarClient db)
{
//异步事务
var result = await db.UseTranAsync(async () =>
{
await db.Insertable(new Student() { Id = "6", Name = "hpf",SchoolId = 2 }).ExecuteCommandAsync();
//throw new Exception(); //手动模拟抛异常
});
if (result.Data==false) //返回值为false
{
if (result.IsSuccess == true)
Console.WriteLine("添加成功");
else
Console.WriteLine("添加失败");
throw result.ErrorException;
}
}
}
8.设置事务隔离级别
目前还没有用到有关知识
8.1 单库模式用法
try
{
db.Ado.BeginTran(IsolationLevel.ReadCommitted);
//业务代码
db.Ado.CommitTran();
}
catch (Exception ex)
{
db.RollbackTran();
throw ex;
}
8.2 多租户模式
var mysqlDb = db.GetConnection("mysql");
var mssqlDb = db.GetConnection("mssql");
try
{
mysqlDb.Ado.BeginTran(IsolationLevel.ReadCommitted);//开启库1的事务
mssqlDb.Ado.BeginTran(IsolationLevel.ReadCommitted);//开启库2的事务
//业务代码 只能用 mysqlDb和 mssqlDb
db.CommitTran();//注意不能用db.ado.CommitTran
}
catch (Exception ex)
{
db.RollbackTran();
throw ex;
}