特别酷炫网站,福建省住房和建设厅网站,外贸进出口公司是干什么的,百度高搜.NET开源 ORM 框架 SqlSugar 系列
【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务… .NET开源 ORM 框架 SqlSugar 系列
【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列【Code First】.NET开源 ORM 框架 SqlSugar 系列【数据事务】.NET开源 ORM 框架 SqlSugar 系列【连接池】.NET开源 ORM 框架 SqlSugar 系列-CSDN博客 数据库事务 数据库事务( transaction )是访问并可能操作各种 数据项 的一个数据库操作 序列这些操作要么全部执行,要么全部不执行是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。 事务特性
原子性(Atomicity)事务中的全部操作在数据库中是不可分割的要么全部完成要么全部不执行。一致性(Consistency)几个并行执行的事务其执行结果必须与按某一顺序 串行执行的结果相一致。隔离性(Isolation)事务的执行不受其他事务的干扰事务执行的中间结果对其他事务必须是透明的。持久性(Durability):对于任意已提交事务系统必须保证该事务对数据库的改变不被丢失即使数据库出现故障。
1、单库事务
单库事务是针 一个db 操作执行的事务无论是 ISqlSugarClient 和 SqlSugarClient 用法都一样 try{db.Ado.BeginTran();db.Insertable(new Order() { .....}).ExecuteCommand();db.Insertable(new Order() { .....}).ExecuteCommand();db.Ado.CommitTran();}catch (Exception ex){db.Ado.RollbackTran();throw ex;} 如果一个db就一个库那么你也可以用多租户事务节约代码因为2者在一个库的情况下作用一样。可以不写 .ado db.BeginTran();//去掉了.adodb.CommitTran();//去掉了.adodb.RollbackTran();//去掉了.ado//ISqlSugarClient 接口使用多租户事务 看文档2.2 2、多库事务可跨库
多数据库事务是SqlSugar独有的功能稳定比 CAP 更强CAP还有一层队列在单个程序中可以很愉快的使用多库事务。
SqlSugarClient 或者 SqlSugarSope 继承于2个接口 代码如下事务 SqlSugarClient : ISqlSugarClient, ITenant 多租户声明 SqlSugarClient db new SqlSugarClient(new ListConnectionConfig()
{new ConnectionConfig(){ ConfigId0, DbTypeDbType.SqlServer,ConnectionString..,IsAutoCloseConnectiontrue},new ConnectionConfig(){ ConfigId1, DbTypeDbType.MySql,ConnectionString..,IsAutoCloseConnectiontrue}
}); 划重点简单的说多租户事务和单库事务用法基本100%一致唯一区别就是少了.Ado
2.1 SqlSugarClient 事务
因为继承 ITenant 了可以直接使用 (老版本var mysqldb.GetConnection要写在事务外面)
注意禁止使用 db.Ado.BeginTran ,多租户是 db.BeginTran //禁止使用 db.Ado.BeginTran,多租户是db.BeginTrantry{db.BeginTran();db.GetConnection(1).Insertable(new Order() { }).ExecuteCommand();db.GetConnection(0).Insertable(new Order() { }).ExecuteCommand();db.CommitTran();}catch (Exception){db.RollbackTran();//数据回滚throw;}//主db
//注入的SqlSugarClient或者SqlSugarScope我们称为主db//子db
//通过租户方法GetConnection出来的我们称为子db用来操作当前数据库没有租户事务相关方法//主db可以用事务管理多个子db 也可以使用 GetConnection等租户方法//目前底层是业务执行成功后统一提交事务业务只要失败全部回滚统一回滚过程中都有有3次重试回滚
//从目前用户使用情况来看相当稳定几乎没有一例失败的反馈
//高安全级别数据请使用差异日志Catch(AggregateException ex)进行补偿机质
//如果回滚失败会throw new AggregateException 2.2 ISqlSugarClient 事务 因为和ITenant没有继承关系需要用 . AsTenAnt() 转换一下 。 db.AsTenant().BeginTran();//低版本 (db as ITenant).BeginTran() db.AsTenant().CommitTran();db.AsTenant().RollbackTran(); 3、调试事务 db.ContextId 要从事务开始CURD 和事务结束 必须一致 这个事务才会生效如果是MYSQL也检查一下表引擎是否支持事务。 ❓不一致怎么办 SqlsugarClient 可以用变量 var db外部Db; 所有操作使用db保证一致。 SqlsuagrScope 该对象是线程安全对象可以单例可以用单例模式保证一致。 测试代码 最好用 Insert 因为 Update 有条件过滤等因素添会添加测试难度我们用插入来进行测试会比较简单些 try{db.BeginTran();Console.WriteLine(db.QueryableOrder().Count());//插入前数量db.Insertable(new Order() { CreateTimeDateTime.Now, Nameaa,Price1}).ExecuteCommand();Console.WriteLine(db.QueryableOrder().Count());//插入后数量throw new Exception(出错);db.CommitTran();}catch{db.RollbackTran();Console.WriteLine(db.QueryableOrder().Count());//回滚后数量} 输出结果 为 155 156 155 插入前和回滚后一样就说明成功的。 4、语法糖
语法糖1 5.0.4才支持
这种适合有 全局异常 的直接出错扔出错并且回滚。 using (var tran db.UseTran()){//业务代码//里面禁止写 try处理事务逻辑格式一定按现在的风格来tran.CommitTran();}//要写 try处理异常可以写在外面 语法糖2自动异常
这种适合 没有异常 处理的减少了try 处理 var result db.UseTran(() {var beginCount db.QueryableOrder().ToList();db.Ado.ExecuteCommand(delete Order);var endCount db.QueryableOrder().Count();return true;// 返回值等行result.Data});if (result.Datafalse) //返回值为false{//result.Data 业务的返回值 //如果是上面的逻辑 result.Datatrue肯定业务成功并且事务成功//if(result.IsSuccessfalse)//事务执行了回滚//if(result.IsSuccesstrue)//事务提交完成} 语法糖3工作单元
UnitOfWork: 工作单元模式/IUnitOfWorK/DbContext - SqlSugar 5x - .NET果糖网
5、跨方法事务
SqlSugarScope 单例模式支持跨事务方法。
SqlSugarClient 需要 IOC 设置 Scoped 周期实现。
6、CAP事务 TCC 和 Saga
6.1 原理讲解 CAP可以支持跨程序间的事务处理非跨程序事务不建议用涉及到队列等在单程序中稳定性肯定不如自带的多租户事务 注意: MySql用户使用 升级到最新 1、数据库的自动释放要关闭 2、手动打开数据库连接 db.Ado.Connection.Open(); 3、用db.Ado.Connection创建事务 4、把你的事务赋值到ORM对象 db.Ado.Transaction 你的事务; 5、执行你的代码 6、关闭Connection对象 //用户使用案例
var dbGetSqlsugarclient();
//关闭自动释放需要 using手动释放
db.CurrentConnectionConfig.IsAutoCloseConnection false;
//取出ADO事务
using (var connection (MySqlConnection)db.Ado.Connection)//SqlServer是SqlConnection
{using (var transaction connection.BeginTransaction(_capBus, autoCommit: false)){if (connection.State ! ConnectionState.Open){connection.Open();}db.Ado.Transaction (IDbTransaction)transaction.DbTransaction;//这行很重要db.InsertableTest(new Test(){name DateTime.Now.ToString()}).ExecuteCommand();_capBus.Publish(Sample.RabbitMQ.MySql, DateTime.Now);transaction.Commit();}
} 7、异步事务 注意请不要在同步方法里面写下面方代码必须是异步方法才行 返回是要带有Task async 。 用法1 try{await db.BeginTranAsync(); await db.Insertable(new Order(){CreateTime DateTime.Now,CustomId 1,Name aaa,Price 0}).ExecuteCommandAsync();await db.CommitTranAsync();}catch (Exception){await db.RollbackTranAsync();} 用法2 //只有5.0.3.8支持老版本请升级使用var res await db.UseTranAsync(async () {await db.Insertable(new Order(){CreateTime DateTime.Now,CustomId 1,Name aaa,Price 0}).ExecuteCommandAsync();return true;//返回值会变成 res.Data});if (result.Datafalse) //返回值为false{ //result.Data 业务的返回值//如果是上面的逻辑 result.Datatrue肯定业务成功并且事务成功//if(result.IsSuccessfalse)//事务执行了回滚//if(result.IsSuccesstrue)//事务提交完成}//注意://await db.UseTranAsync 前面的await不要漏掉了 8、设置事务隔离级别
单库模式用法 try
{db.Ado.BeginTran(IsolationLevel.ReadCommitted);//业务代码 db.Ado.CommitTran();
}
catch (Exception ex)
{db.RollbackTran();throw ex;
} 多租户模式 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;
} 9、嵌套事务支持异步 9.1. 共享模式
有外部事务内部事务用外部事务推荐
通过 工作单元 实现嵌套事务 5.1.2.5-preview03 //db.Ado.IsNoTran()表示事务为null才开启事务using (var uow db.CreateContext(db.Ado.IsNoTran())) {using (var uow2 db.CreateContext(db.Ado.IsNoTran())){ uow2.Commit();}uow.Commit(); //禁止用 db.RollBack 工作单元内只要throw会自动回滚} 9.2. 子事务独立 不推荐
不推荐原因这种很容易出现坑比如业务A和业务B都用到了一样的表就会死锁
事务嵌套推荐用9.1或者标题10 9.2是不推荐的 try{db.BeginTran();//业务..Avar childDbdb.CopyNew();try{childDb.BeginTran();//...业务BchildDb.Commit();}catch (Exception){childDb.RollbackTran();//数据回滚throw;}db.CommitTran();}catch (Exception){db.RollbackTran();//数据回滚throw;} 10、工作单元【事务特性】
在 .NET Core 中可以使用自定义的 ActionFilter 来封装事务。 [ServiceFilter(typeof(TransactionFilter))]//加上这行就可以用了public IEnumerableWeatherForecast Get(){.....数据库操作... } 10.1 创建全局事务 public class TransactionFilter : IActionFilter{ISqlSugarClient _db;//你也可以换EF CORE对象 或者ADO对象都行public TransactionFilter(ISqlSugarClient db)//ISqlSugarClient需要IOC注入处理事务的对象{ _dbdb;}public void OnActionExecuting(ActionExecutingContext context){_db.AsTenant().BeginTran();//接口要加.AsTenant()}public void OnActionExecuted(ActionExecutedContext context){if (context.Exception null){_db.AsTenant().CommitTran();}else{_db.AsTenant().RollBack();}}} 10.2 IOC注册 //注入事务对象
builder.Services.AddScopedTransactionFilter();//注入ORM对象
//注册上下文AOP里面可以获取IOC对象如果有现成框架比如Furion可以不写这一行
services.AddHttpContextAccessor();
//注册SqlSugar
services.AddSingletonISqlSugarClient(s
{SqlSugarScope sqlSugar new SqlSugarScope(new ConnectionConfig(){DbType SqlSugar.DbType.Sqlite,ConnectionString DataSourcesqlsugar-dev.db,IsAutoCloseConnection true,},db {//单例参数配置所有上下文生效db.Aop.OnLogExecuting (sql, pars) {//获取作IOC作用域对象//var appServive s.GetServiceIHttpContextAccessor();//var obj appServive?.HttpContext?.RequestServices.GetServiceLog();//Console.WriteLine(AOP obj.GetHashCode());};});return sqlSugar;
}); 10.3 在接口打上事务 [ServiceFilter(typeof(TransactionFilter))]//加上这行就可以用了[HttpGet(Name GetWeatherForecast)]public IEnumerableWeatherForecast Get(){.....数据库操作... } 11、MySql注意事项
1MYSQL不支持创建表和删除表处理事务,原生事务也一样 。
2MyISAM 存储引擎不支持事务 需要改成 InnoDB 。