与Dapper .NET的交易

问题描述 投票:1回答:2

我目前在一层中有两个类,它们将数据包含在数据库中:

using Dapper;
using System;
using System.Data.SqlClient;
using System.Linq;

namespace repositories
{
    public class DAOBook
    {
        private readonly string _connection;

        public DAOBook(string databaseConnection)
        {
            _connection = databaseConnection;
        }

        public bool IncludeBook(string title)
        {
            try
            {
                using (var connection = new SqlConnection(_connection))
                {
                    var sql = $@"
                                INSERT INTO books
                                  (title)
                                VALUES
                                  ('{title}' ";

                    var result = connection.Execute(sql);

                    return result != 0;
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"{ex.Message}", ex);
            }
        }
    }
}

using Dapper;
using System;
using System.Data.SqlClient;
using System.Linq;

namespace repositories
{
    public class DAOBookTag
    {
        private readonly string _connection;

        public DAOBookTag(string databaseConnection)
        {
            _connection = databaseConnection;
        }

        public bool IncludeBookTag(string tag, int userid)
        {
            try
            {
                using (var connection = new SqlConnection(_connection))
                {
                    var sql = $@"
                                INSERT INTO bookTag
                                  (tag, userid)
                                VALUES
                                  ('{tag}', {userid} ";

                    var result = connection.Execute(sql);

                    return result != 0;
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"{ex.Message}", ex);
            }
        }
    }
}

在我的服务层中,我可以正常调用这两个类,然后将它们插入数据库。

try
{
    var connectionString = "<my_connection_string>";
    var daoBook = new DAOBook(connectionString);
    var daoBookTag = new DAOBookTag(connectionString);

    dao.IncludeBook("Alice");
    dao.IncludeBookTag("Romance", 1);
}
catch (Exception ex)
{
    throw new Exception($"{ex.Message}", ex);
}

但是,我想放置一个事务控件,以便在第二类的插入发生错误的情况下,它会取消catch中的事务,如下所示:

try
{
    var connectionString = "<my_connection_string>";
    var daoBook = new DAOBook(connectionString);
    var daoBookTag = new DAOBookTag(connectionString);

    // begin transaction    
    dao.IncludeBook("Alice");
    dao.IncludeBookTag("Romance", 1);
    // commit
}
catch (Exception ex)
{
    // rollback
    throw new Exception($"{ex.Message}", ex);
}

我知道这一定是一个初学者的问题,但是我似乎找不到两个持久化类共享同一事务的方法。

我看到了实现Dapper事务控制的示例,但是我不知道如何在服务层(而不是持久层)中实现它。https://riptutorial.com/dapper/example/22536/using-a-transaction

谢谢

c# .net oracle transactions dapper
2个回答
1
投票

使用TransactionScope

using (var transactionScope = new TransactionScope())
{
    var connectionString = "<my_connection_string>";
    var daoBook = new DAOBook(connectionString);
    var daoBookTag = new DAOBookTag(connectionString);

    // begin transaction    
    dao.IncludeBook("Alice");
    dao.IncludeBookTag("Romance", 1);
    //commit
    transactionScope.Complete();
}

https://dapper-tutorial.net/transaction


0
投票

[在ADO.NET中有两种处理事务的方法;通常首选的机制是ADO.NET事务,即BeginTransaction。这有局限性,但效率很高,并且可以本地映射到大多数提供程序。 ADO.NET事务的关键限制是它仅跨越一个连接,并且您的连接必须至少持续与事务一样长的时间。

就Dapper的使用而言,您还必须将事务into]传递给调用;例如:

using (var conn = new SqlConnection(connectionString))
{
    connection.Open();
    using (var tran = connection.BeginTransaction())
    {
        // ... your work
        tran.Commit();
    }
}

这里“您的工作”有效地使用相同的conntran实例,使用:

var result = conn.Execute(sql, args, transaction: tran);

lazyer

方法是使用TransactionScope。使用起来比较简单,但是更多参与。我通常不建议这样做,但是它可以工作。

您还应该参数化:

var sql = @"
INSERT INTO bookTag (tag, userid)
VALUES (@tag, @userId)";
var result = connection.Execute(sql, new { tag, userId });
© www.soinside.com 2019 - 2024. All rights reserved.