我在我的项目中使用C#,EF和Microsoft SQL Server。我需要将整个数据库锁定在其中一台机器上以使其与Active Directory同步。锁定数据库,使用C#
许多机器都可以访问数据库,所以我需要防止从另一台机器读取,插入或更新我的数据库。
简单的例子,我现在做:
using (DB context = new DB())
using (var ts = context.Database.BeginTransaction(System.Data.IsolationLevel.Serializable))
{
context.Database.Connection.Open();
try
{
string sql = SQLProperties.getInstance().CurrentPropeties["User_Insert"];
StringBuilder sb = new StringBuilder(10240);
for (int chunkCount = 0; chunkCount < Math.Ceiling((decimal)count/commitCount); chunkCount++)
{
using (SqlCommand command = new SqlCommand())
{
command.Transaction = (SqlTransaction)ts.UnderlyingTransaction;
for (var i = 1; i <= commitCount; i++)
{
string query = sql;
int ind = chunkCount * commitCount + i;
query = string.Format(query, ind);
sb.Append(query);
//fill command.Params
}
command.Connection = (SqlConnection)context.Database.Connection;
command.CommandText = sb.ToString();
command.ExecuteNonQuery();
}
sb.Clear();
}
ts.Commit();
}
catch (Exception ex)
{
ts.Rollback();
}
}
但当ExecuteNonQuery()
被调用时,将查询发送到数据库和执行。当我准备SqlCommand
时,即使我使用单个事务,另一台机器也可以读取,插入或更新数据库中的数据。我需要禁用它。
另外我需要做的很多与数据库中的表中的数据的更改,所以我希望在同步锁定整个数据库。
我知道在Server Management Studio中,我可以使用GO语句进行批量SQL查询,但SqlCommand
不支持这一个语句。此外,我尝试使用此方法发送GO语句:
ServerConnection svrConnection = new ServerConnection((SqlConnection)context.Database.Connection);
Server server = new Server(svrConnection);
int f = server.ConnectionContext.ExecuteNonQuery("LOCK TABLES dbo.User WRITE");
但似乎它不起作用。
如何从C#代码执行此操作?
增加:我如何能同步两个可能的交易在同一时间开始?现在我有一个事务,当一个事务开始在表中插入用户时,例如,在500个用户之后,另一个事务插入用户和表包含来自两个事务的混合数据。我如何订购他们?
GO不是t-sql语句。它是SSMS中的默认批终止符。你的问题是什么? –
我很想知道为什么你需要锁定整个数据库(甚至是所有数据库中的单个表)。大多数现代数据库系统(包括SQL Server)允许非常好的并发性。你想通过锁定整个事物来防止什么现象? –
同步可以同时从两台机器启动,但它们都具有用于同步的公共数据。我需要锁定一些表格以防止双重插入的数据。 这就是为什么我想拒绝访问表。同步数据可能包含10 000多个用户和电子邮件,还需要删除旧数据或将其升级到新状态。 或者我可以用大量的sql查询构建文件并在一个事务中处理它以防止数据库锁定? SqlCommand对像C#中的2100这样的参数有限制。 –