天天看点

netcore使用sqlsugar实现分布式事务(强一制性)

适用于:

同实例下的单库:test(sqlserver-localhost)

同实例下的不同库:test(sqlserver-localhost),test2(sqlserver-localhost)

同类型数据库不同实例:test(sqlserver-localhost),test2(sqlserver-remote)

另:不同类/异构数据库的不同实例:执行数据的操作要放在一起,保持Db对象不变,test(sqlserver-localhost),test2(mysql-remote)

1.DbContext.cs文件声明多库

Db = new SqlSugarClient(new List<ConnectionConfig>()
{
	new ConnectionConfig(){ ConfigId="1", ConnectionString = "server=.\\SQLEXPRESS;uid=sa;pwd=123456;database=test",
				DbType = DbType.SqlServer,
				InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
				IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了
	},
	new ConnectionConfig(){ ConfigId="2",ConnectionString ="server=.\\SQLEXPRESS;uid=sa;pwd=123456;database=test2",
				DbType = DbType.SqlServer,
				InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
				IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了
	}
});
           

2.数据层声明写入库的不同方法

public void IdTest(long id)
        {
            IDLog model = new IDLog();
            model.ID = id;
            model.Dt = DateTime.Now;
            Db.ChangeDatabase("1");//test库,默认是第一个库
            Db.Insertable(model).ExecuteCommand();

        }
        public void IdTest2(long id)
        {
            IDLog model = new IDLog();
            model.ID = id;
            model.Dt = DateTime.Now;
            Db.ChangeDatabase("2"); //切换到test2库
            Db.Insertable(model).ExecuteCommand();
            //throw new Exception("error");
        }
           

 3.使用分布式事务语法,同类或者同实例时可用,如果是异构型数据库请使用4

                   Task.Run(() =>
                    {
                        var bb = new IDLogTester();
                        try
                        {
                            bb.Db.BeginTran();
                            Console.WriteLine("------------------------------------------------------------");
                            Console.WriteLine("我是-子线程-分布式事务");
                            Console.WriteLine("线程ID:" + Thread.CurrentThread.ManagedThreadId);
                            //sqlserver-localhost-test
                            bb.IdTest(7);
                            //同实例或同类型数据库:sqlserver-remote(localhost)-test2
                            bb.IdTest2(7);

                            bb.Db.CommitTran();
                        }

                        catch (Exception ex)
                        {
                            bb.Db.RollbackTran();
                            throw;
                        }
                        finally
                        {

                        }
                    });
           

另:4.异构型数据库分布式事务实现:所有的数据库操作需放在一起。

4-1. 先修改DbContext.cs文件声明多库

Db = new SqlSugarClient(new List<ConnectionConfig>()
{
	new ConnectionConfig(){ ConfigId="1", ConnectionString = "server=.\\SQLEXPRESS;uid=sa;pwd=123456;database=test",
				DbType = DbType.SqlServer,
				InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
				IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了
	},
	new ConnectionConfig(){ ConfigId="2",ConnectionString ="sserver=localhost; port=3306; uid=root; pwd=root; database=test",
				DbType = DbType.MySql,
				InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
				IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样我就不多解释了
	}
});
           

 4-2.把数据库操作放在一起,保持Db对象不变

var sqlsugarDbDb = new IDLogTester().Db;
            try
            {
                sqlsugarDbDb.BeginTran();

                sqlsugarDbDb.ChangeDatabase("1");
                sqlsugarDbDb.Insertable<ConsoleApp1.IDLog>(new ConsoleApp1.IDLog {ID=8,Dt=DateTime.Now }).ExecuteCommand();

                sqlsugarDbDb.ChangeDatabase("2");//使用库2
                sqlsugarDbDb.Insertable<ConsoleApp1.IDLog>(new ConsoleApp1.IDLog { ID = 18, Dt = DateTime.Now }).ExecuteCommand();

                sqlsugarDbDb.CommitTran();
            }
            catch (Exception ex)
            {
                sqlsugarDbDb.RollbackTran();
                Console.WriteLine(ex.Message);
            }
           

继续阅读