微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

sql-server – 使用SqlConnection / System.Transactions的Session-Per-Request

我刚刚开始使用Dapper进行项目,在过去几年中大多使用过NHibernate和EF等ORM.

通常在我们的Web应用程序中,我们实现每个请求的会话,在请求开始时开始一个事务,并在最后提交它.

我们应该在与sqlConnection / System.Transactions直接工作时做类似的事情吗?

StackOverflow如何做?

接受@gbn和@Sam Safron的建议我没有使用交易.在我的情况下,我只是读取查询,所以似乎没有真正的要求使用事务(与我已经被告知有关隐式事务).

我创建一个轻量级的会话接口,以便我可以根据请求使用连接.这对我来说是非常有益的,与Dapper一样,我经常需要创建一些不同的查询来构建一个对象,而不是共享相同的连接.

对每个请求进行连接的处理工作由IoC容器(StructureMap)完成:

public interface ISession : Idisposable {
    IDbConnection Connection { get; }
}

public class DbSession : ISession {

    private static readonly object @lock = new object();
    private readonly ILogger logger;
    private readonly string connectionString;
    private IDbConnection cn;

    public DbSession(string connectionString,ILogger logger) {
        this.connectionString = connectionString;
        this.logger = logger;
    }

    public IDbConnection Connection { get { return GetConnection(); } }

    private IDbConnection GetConnection() {
        if (cn == null) {
            lock (@lock) {
                if (cn == null) {
                    logger.Debug("Creating Connection");
                    cn = new sqlConnection(connectionString);
                    cn.open();
                    logger.Debug("Opened Connection");
                }
            }
        }

        return cn;
    }

    public void dispose() {
        if (cn != null) {
            logger.Debug("disposing connection (current state '{0}')",cn.State);
            cn.dispose();
        }
    }
}

解决方法

这就是我们所做的:

我们在称为Current的对象上定义了一个静态的称为DB

public static DBContext DB
{
    var result = GetContextItem<T>(itemKey);

    if (result == null)
    {
        result = InstantiateDB();
        SetContextItem(itemKey,result);
    }

    return result;
}

public static T GetContextItem<T>(string itemKey,bool strict = true)
{

#if DEBUG // HttpContext is null for unit test calls,which are only done in DEBUG
    if (Context == null)
    {
        var result = CallContext.GetData(itemKey);
        return result != null ? (T)result : default(T);
    }
    else
    {
#endif
        var ctx = HttpContext.Current;
        if (ctx == null)
        {
            if (strict) throw new InvalidOperationException("GetContextItem without a context");
            return default(T);
        }
        else
        {
            var result = ctx.Items[itemKey];
            return result != null ? (T)result : default(T);
        }
#if DEBUG
    }
#endif
}

public static void SetContextItem(string itemKey,object item)
{
#if DEBUG // HttpContext is null for unit test calls,which are only done in DEBUG
    if (Context == null)
    {
        CallContext.SetData(itemKey,item);
    }
    else
    {
#endif
        HttpContext.Current.Items[itemKey] = item;

#if DEBUG
    }
#endif
}

在我们的例子中,InstantiateDB返回一个L2S上下文,但是在你的情况下,它可能是一个打开的sqlConnection或其他任何东西.

在我们的应用程序对象上,我们确保我们的连接在请求结束时关闭.

protected void Application_EndRequest(object sender,EventArgs e)
   {
        Current.disposeDB(); // closes connection,clears context 
   }

然后在你需要访问数据库代码中的任何地方,你简单地调用Current.DB和东西自动工作.这也是单元测试友好,由于所有#if DEBUG的东西.

我们不会在每个会话中开始任何交易,如果我们在会话开始时进行了更新,我们会遇到严重的锁定问题,因为锁将不会被释放直到结束.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


SELECT a.*,b.dp_name,c.pa_name,fm_name=(CASE WHEN a.fm_no=&#39;LJCG001H&#39; THEN dbo.ELTPNAME(a.fw_nu) ELSE d.fm_name END),e.fw_state_nm,f.fw_rmk_nm
if not exists(select name from syscolumns where name=&#39;tod_no&#39; and id=object_id(&#39;iebo09d12&#39;)) alter table iebo09d12 add tod_no varchar(
select a.*,pano=a.pa_no,b.pa_name,f.dp_name,e.fw_state_nm,g.fa_name from LJSS007H a (nolock) Left join LJPA002H b (nolock) On a.pa_no =b.pa_no Left jo
要在 SQL Server 2019 中设置定时自动重启,可以使用 Windows 任务计划程序。下面是详细的步骤: 步骤一:创建批处理文件 打开记事本。 输入以下内容: net stop &quot;SQL Server (MSSQLSERVER)&quot; net start &quot;SQ
您收到的错误消息表明数据库 &#39;EastRiver&#39; 的事务日志已满,导致数据库操作失败。要解决这个问题,可以按照以下步骤操作: 1. 备份事务日志首先,备份事务日志以释放空间: BACKUP LOG [EastRiver] TO DISK = N&#39;C:\Backup\East
首先我需要查询出需要使用SQL Server Profiler跟踪的数据库标识ID,若不知道怎么查询数据库的标识ID, 打开SQL Server management studio,点击工具。选择SQL Server Profiler。 登录,登录成功后,如果有个默认弹窗,先取消 新建追踪 命名
--最新的解决方法 --先创建用户帐户,不进行授权,然后通过下面的SQL语句将该用户帐户关联至对应的数据库用户。优点是避免了重新授权的操作。 USE tempdbEXEC sp_change_users_login &#39;Update_One&#39;, &#39;iemis&#39;, &#3
命令: ALTER TABLE 表名 add 列名 数据类型 default 默认值 not null 例如: ALTER TABLE LJEL005H add el_req int default 15 not null
declare @i int set @i=340 while @i&lt;415 begin set @i=@iʱ insert into LJWK007H select &#39;2024&#39;,&#39;28&#39;,&#39;9110&#39;,&#39;3PTSD621000000