gpt4 book ai didi

c# - 将 TransactionScope 与 MySQL 和读锁一起使用

转载 作者:行者123 更新时间:2023-11-29 05:00:48 25 4
gpt4 key购买 nike

我有以下情况:

如果有一个带有 InnoDB 表的 MySQL 数据库,我用它来存储唯一数字。我启动一个事务,读取值(例如 1000471),将该值存储在另一个表中并更新增量值(100472)。现在我想避免其他人甚至在我的事务运行时读取值。

如果我使用纯 MySQL,我会这样做:

Exceute("LOCK tbl1 READ");
执行("SELECT ... from tbl1");
执行(“插入到 tbl2”);
执行("解锁表");

但由于我使用 SubSonic 作为 DAL,并且代码应该独立于 mysql,所以我必须使用 TransactionScope。

我的代码:

        TransactionOptions TransOpt = new TransactionOptions();
TransOpt.IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted;
TransOpt.Timeout = new TimeSpan(0, 2, 0);

using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew, TransOpt))
{

// Select Row from tbl1

// Do something

ts.Complete();
}

根据TransactionOptions的帮助

system.transactions.isolationlevel

我想要达到的效果可以用 IsolationLevel.ReadCommitted 实现,但我仍然可以从事务外部读取行(如果我尝试更改它,我会得到一个锁,所以事务正在运行)

有人有什么建议吗?使用 TransactionScope 甚至可以实现读锁

最佳答案

如果有人感兴趣,这就是 TransactionOptions 影响 MySql 的方式:

假设我有两种方法。

方法 1 启动一个事务,从我的表中选择一行,增加值并更新表。

方法2是一样的,但是在select和update之间我加了1000ms的sleep。

现在假设我有以下代码:

    Private Sub Button1_Click(sender as Object, e as System.EventArgs) Handles Button1.Click

Dim thread1 As New Threading.Thread(AddressOf Method1)
Dim thread2 As New Threading.Thread(AddressOf Method2)

thread2.Start() // I start thread 2 first, because this one sleeps
thread1.Start()

End Sub

如果没有交易,这会发生:
线程2启动,读取值5,然后休眠,
线程1启动,读取值5,更新值6,
线程 2 也将值更新为 6。

作用:我有两次唯一编号。

我想要的:
线程2启动,读取值5,然后休眠,
thread1 启动,尝试读取值,但获得锁并休眠,
thread2 将值更新为 6,
线程1继续,读取值6,将值更新为7

这就是如何使用 TransactionScope 开始交易:

        TransactionOptions Opts = new TransactionOptions();
Opts.IsolationLevel = IsolationLevel.ReadUncommitted;

// start Transaction
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.RequiresNew, Opts))
{
// Do your work and call complete
ts.Complete();
}

那甚至可以管理分布式事务。如果抛出异常,则永远不会调用 ts.Complete,并且范围的 Dispose() 部分会回滚事务。

下面概述了不同的 IsolationLevels 如何影响交易:

  • IsolationLevel.Chaos
    抛出 NotSupportedException - 不支持混沌隔离级别

  • IsolationLevel.ReadCommited
    事务不会相互干扰(两次相同的读取,错误)

  • IsolationLevel.ReadUncommitted
    事务不会相互干扰(两次相同的读取,错误)

  • IsolationLevel.RepeatableRead
    事务不会相互干扰(两次相同的读取,错误)

  • IsolationLevel.Serializable
    抛出 MySqlException - 尝试获取锁时发现死锁;尝试在更新期间重新启动事务

  • IsolationLevel.Snapshot
    抛出 MySqlException - 你的 SQL 语法有错误;查看与您的 MySQL 服务器版本对应的手册,了解在 Connection.Open() 期间在第 1 行附近使用的正确语法

  • IsolationLevel.Unspecified
    抛出 MySqlException - 尝试获取锁时发现死锁;尝试在更新期间重新启动事务

  • 未设置交易选项
    抛出 MySqlException - 尝试获取锁时发现死锁;尝试在更新期间重新启动事务

关于c# - 将 TransactionScope 与 MySQL 和读锁一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/938801/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com