Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use distributed transaction ? #58

Closed
zanpen2000 opened this issue Nov 23, 2017 · 5 comments
Closed

How to use distributed transaction ? #58

zanpen2000 opened this issue Nov 23, 2017 · 5 comments

Comments

@zanpen2000
Copy link

我测试的代码如下,想测试事务一致性,订阅者手动抛出了一个异常,期望在这种情况下本地业务回进行事务回滚,但最终结果是本地业务(PersonInsert插入成功并未回滚)也许是我的理解或使用方式不对?请指点一下,谢谢!

 [Route("publish")]
        public IActionResult PublishMessage([FromServices]ICapPublisher _publisher)
        {
            var sqlOptions = (SqlServerOptions)HttpContext.RequestServices.GetService(typeof(SqlServerOptions));
            var cstr = sqlOptions.ConnectionString;
            using (var sqlconnection = new SqlConnection(cstr))
            {
                sqlconnection.Open();
                using (var sqlTrans = sqlconnection.BeginTransaction())
                {
                    var person = new Person { Name = "老张", Age = 50 };
                    PersonInsert(sqlTrans, person); // 我的业务代码(向数据库插入一条记录), 这里不抛出异常,数据库插入记录成功
                    _publisher.Publish("CapDemo", person, sqlTrans); //接收并打印消息,手动抛了个异常
                    sqlTrans.Commit();
                }

                //最终结果是 PersonInsert(本地业务插入成功,订阅者抛出异常,但本地业务没有回滚)
            }
            return Ok();
        }

        /// <summary>
        /// 订阅者业务
        /// </summary>
        /// <param name="person"></param>
        [NonAction]
        [CapSubscribe("CapDemo")]
        public void ReceiveMessage(Person person)
        {
            var cstr = "Data Source=192.168.0.250;Initial Catalog=CapDemo;User ID=sa;Password=123123;";

            using (var sqlconnection = new SqlConnection(cstr))
            {
                sqlconnection.Open();
                using (var trans = sqlconnection.BeginTransaction())
                {
                    try
                    {
                        sqlconnection.Execute($"insert into Person(Name, Age) values('{person.Name} + _subscribe', {person.Age})", null, trans);
                        Console.WriteLine("received message: {0}", person.ToString());
                        throw new Exception("订阅者抛出异常检查事务性");
                        trans.Commit();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                        trans.Rollback();
                    }
                }
            }
        }

        /// <summary>
        /// 本地业务逻辑
        /// </summary>
        /// <param name="trans"></param>
        /// <param name="person"></param>
        /// <returns></returns>
        [NonAction]
        private int PersonInsert(SqlTransaction trans, Person person)
        {
            var sqlconnection = trans.Connection;

            // check connection
            if (sqlconnection.State == System.Data.ConnectionState.Closed) sqlconnection.Open();

            var sql = $"insert into person (Name, Age) values ('{person.Name}', {person.Age})";
            int row_count = sqlconnection.Execute(sql: sql, transaction: trans);
            return row_count;
        }
@yang-xiaodong
Copy link
Member

@yang-xiaodong
Copy link
Member

设为关闭。 如果还有其他问题,请 reopen

@zanpen2000
Copy link
Author

@yuleyule66 谢谢回复,是不是如果消费方业务上面失败,需要给生产方发送一个业务补偿消息,通知生产方进行回滚等操作?

@yang-xiaodong
Copy link
Member

yang-xiaodong commented Nov 24, 2017

@zanpen2000 是的,发送消息的时候,可以指定一个callbackname,这个就是补偿用的方法。

@yang-xiaodong
Copy link
Member

Duplicate to #60

@yang-xiaodong yang-xiaodong changed the title 事务一致性的功能如何使用呢? How to use distributed transaction ? Nov 25, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants