什么是使用SQLTransaction的适当时间?
我将它们用于所有 INSERT,UPDATE和DELETE语句.
这是正确的用法还是我有点矫枉过正?
下面的sproc是根据本文中的模板实现的:异常处理和嵌套事务.这个sproc应该处理死锁,它由已经创建事务的另一个sproc调用.内部事务的BEGIN/COMMIT的一些魔法是不匹配的,因为我得到了这个例外:Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 0.据我所知,catch被执行,@xstate = -1是真的,整个外部事务被回滚.
任何不匹配发生的想法?
CREATE PROCEDURE [dbo].[mysproc]
AS
BEGIN
SET NOCOUNT ON;
SET DEADLOCK_PRIORITY LOW;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
BEGIN TRY
DECLARE @trancount int;
SET @trancount = @@TRANCOUNT;
IF (@trancount = 0)
BEGIN TRANSACTION;
ELSE
SAVE TRANSACTION InnerTran;
--
-- do some work that can potentially cause a deadlock
--
END TRY …Run Code Online (Sandbox Code Playgroud) t-sql sql-server nested-transactions sql-server-2008 sqltransaction
我有一个场景,屏幕上的用户操作导致在大约50个不同的表中实时创建新记录.用例的设计使得用户操作创建的新记录立即需要用户进行更改.所以没有离线或延迟创作的可能性.
话虽如此,显而易见的问题是 - 插入语句(以及一些额外的操作语句)都在事务中,这使得它成为一个非常冗长的事务.这将运行大约30秒,通常会导致超时或阻止其他查询.
原子性需要交易.有没有更好的方法可以拆分事务并保持一致性?或任何其他方法来改善目前的情况?
我有一个SEQUENCE用于设置表的事务对开的表:
CREATE SEQUENCE [Seq].[Folio]
AS [bigint]
START WITH 114090
INCREMENT BY 1
MINVALUE -9223372036854775808
MAXVALUE 9223372036854775807
CACHE
Run Code Online (Sandbox Code Playgroud)
今天只是为了好奇我做了一个:
SELECT folio
FROM transactions
ORDER BY folio DESC
Run Code Online (Sandbox Code Playgroud)
如果有差距会有什么意外,因此表中缺少对开页.
例:
这意味着事情正在发生.只是为了提供更多信息,INSERT我使用的存储过程之前有以下内容INSERT INTO...
DECLARE @numfolio int
SELECT @numfolio = NEXT VALUE FOR Seq.Folio
Run Code Online (Sandbox Code Playgroud)
从我的应用程序保存信息时,我使用了数据库事务,所以如果一切顺利,那么应用程序会执行COMMIT TRANSACTION,如果不是,我会执行此操作ROLLBACK TRANSACTION.
我认为问题的根源是事务,所以当出现错误NEXT VALUE时,序列已经生成,并且ROLLBACK对此没有影响.
有任何线索如何解决这个问题,以便有一个没有间隙的完美序列?
模块化编程是正确的方法,但它有时会导致需要额外努力和研究的问题.我有三个数据库插入函数,比如InsertName(),InsertAddress(),InsertPhoneNo()以它为例.如果在任何函数中发生异常,则必须执行所有这些函数,不会对数据库进行任何更改.
我能做的就是合并所有三合一并使用sqltransaction.
InsertDetails()
{
using (SqlTransaction sqlTransaction = cn.BeginTransaction())
{
using (SqlCommand cm = new SqlCommand())
{
cm.Transaction = sqlTransaction;
InsertName();//Code to insert name
Insertaddress();//code to insert address
InsertPhoneNo();//code to insert phone no
}
sqlTransaction.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
但上面的解决方案违背了我的模块化方法.是否可以将多个函数绑定到一个sql事务而不合并它们,如果不是哪种方法可以实现这一点.
我想用 SQL Server 中的另一个阿拉伯字符替换 select 语句中的阿拉伯字符,示例查询:
select replace(ArabicName, '?', '?') as ArabicName from dataIndividual;
Run Code Online (Sandbox Code Playgroud)
但它不会替换,原因可能是 SQL 服务器不会将字符读取为Unicode而是ASCII(我猜)。
有没有办法为replace函数传递 Unicode 字符?
注意:我已经尝试collate过阿拉伯字符。
我有一些要执行的代码,如下所示。但是在第二次迭代中,我不断收到异常“此SqlTransaction已完成;它不再可用”。有人可以帮我指出我在这里做错了吗?谢谢!
SqlConnection cn = (SqlConnection)SqlConnectionManager.Instance.GetUserConnection(user);
cn.Open();
try
{
foreach (Master mRecord in masterList)
{
if (sqlTransaction == null)
sqlTransaction = cn.BeginTransaction();
SqlCommand cm = cn.CreateCommand();
cm.Transaction = sqlTransaction;
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "pr_InsertRecords";
try
{
cm.ExecuteNonQuery();
Debug.WriteLine("Auditor.Write: end sql table value param");
sqlTransaction.Commit();
sqlTransaction.Dispose();
}
catch (Exception Ex)
{
Debug.WriteLine(" Exception message: " + Ex.Message);
if (Ex.InnerException != null)
{
Debug.WriteLine("Inner exception message" + Ex.InnerException.Message);
}
sqlTransaction.Rollback();
}
}
}
finally
{
cn.Close();
}
Run Code Online (Sandbox Code Playgroud) 我正在使用perl与外部提供的sqlite数据库为静态服务的网站预生成大约9k页面.
我对原始数据进行了一些算法改进,但为了保持一致,我认为如果我的脚本单独保留原始数据库并且只在内存中修改数据会更有意义(如果需要,甚至整个数据库都应该适合在生成网页之前,没有任何问题的RAM.
我该怎么做呢?
我闻到我可以从这里的某种SQL事务功能中受益(在我的脚本完成后应该放弃),这是正确的吗?考虑到想要保持原始数据库文件不被修改的约束,这听起来是个好主意吗?(例如,当使用来自Perl的SQLite时,来自正在进行的事务的数据存储在何处以及如何存储?)任何其他方式来完成我需要的东西?(我是perl和sql新手 - 寻找带注释的代码示例.)
我想作为最后的手段,我总是可以在文件系统中复制数据库文件,但这看起来像是一个丑陋而低效的解决方案.
为简单起见假设我有两张桌子
user table (id, email)
user log table (id, date)
无论在用户表中插入什么id,都应该在user_log表中插入相同的id,否则事务应该失败.
我怎样才能做到这一点
BEGIN TRANSACTION
INSERT into user(id, email) OUTPUT Inserted.id (1, 'a@x.com', 'x'), (2, 'b@x.com', 'y')
// I also want to be able to do
INSERT into user_log(id, date) values(1, date), (2, date)
COMMIT TRANSACTION
Run Code Online (Sandbox Code Playgroud) 作为学习练习,在尝试使用任何ORM(如EF)之前,我想使用ADO.NET和存储过程构建个人项目.
因为我不希望我的代码随着时间的推移变得混乱,我想使用一些模式,如存储库和UoW模式.
除了交易处理之外,几乎所有事情都已经解决了.
为了某种方式"模拟"一个UoW,我使用了@jgauffin 提供的这个类,但阻止我使用该类的是每次你创建该类的新实例(AdoNetUnitOfWork)时,你自动开始一个事务并且有很多您只需要读取数据的情况.
在这方面,这是我在我读过的一本SQL书中找到的:
在事务中执行SELECT语句可以在引用的表上创建锁定,这可以阻止其他用户或会话执行工作或读取数据
这是AdoNetUnitOfWork班级:
public class AdoNetUnitOfWork : IUnitOfWork
{
public AdoNetUnitOfWork(IDbConnection connection, bool ownsConnection)
{
_connection = connection;
_ownsConnection=ownsConnection;
_transaction = connection.BeginTransaction();
}
public IDbCommand CreateCommand()
{
var command = _connection.CreateCommand();
command.Transaction = _transaction;
return command;
}
public void SaveChanges()
{
if (_transaction == null)
throw new InvalidOperationException("Transaction have already been commited. Check your transaction handling.");
_transaction.Commit();
_transaction = null;
}
public void Dispose()
{
if (_transaction != null) …Run Code Online (Sandbox Code Playgroud) 我有一个名为a26 行的表:
Select * from a
Run Code Online (Sandbox Code Playgroud)
输出为 26
Begin Tran
Truncate table a
Select * from a
Run Code Online (Sandbox Code Playgroud)
输出为零行
Rollback Tran
Select * from a
Run Code Online (Sandbox Code Playgroud)
输出又是 26 行
截断是 ddl 命令,我们无法执行回滚操作,那么为什么回滚后我们得到相同数量的行?
请详细确认。
我想弄清楚我需要在这里使用:删除,插入或更新.
基本上.
当主表更新时,我需要将一些数据写入历史表,并且只有当状态从某些内容更改为挂起或活动时才需要.
这就是我现在拥有的:
ALTER TRIGGER [dbo].[trg_SourceHistory] ON [dbo].[tblSource]
FOR UPDATE AS
DECLARE @statusOldValue char(1)
DECLARE @statusNewValue char(1)
SELECT @statusOldValue = statusCode FROM deleted
SELECT @statusNewValue= statusCode FROM updated
IF (@statusOldValue <> @statusNewValue) AND
(@statusOldValue = 'P' or @statusOldValue = 'A')
BEGIN TRY
INSERT * INTO tblHistoryTable)
select * from [DELETED]
Run Code Online (Sandbox Code Playgroud)
所以我希望新数据保留在主表中,历史表将被覆盖的内容更新...现在它只是复制相同的信息.所以更新后,我的两个表都有相同的数据.
sqltransaction ×12
sql-server ×8
sql ×5
c# ×4
database ×2
t-sql ×2
.net ×1
ado.net ×1
data-access ×1
perl ×1
sqlite ×1
transactions ×1
triggers ×1
unicode ×1
unit-of-work ×1