`

事务ROLLBACK关闭游标CURSOR问题原因及解决方案

    博客分类:
  • DB
阅读更多

      大部分数据库,包括MS SqlServer, DB2, Oracle的事务都会影响游标.最常见的错误就是在游标中嵌入了一组事务,这时会导致数据库报错.
其原因是:
      数据库程序中很重要的一点就是事务处理(transaction或者the unit of work(UOW))。事务当中的任何一部分失败,整个事物就会失败。利用COMMIT和ROLLBACK进行适当的事务控制对于保证数据完整性来说是至关重要的。
      当在使用游标的时候使用COMMIT或者ROLLBACK语句时,游标的行动取决于是否在生命的时候加了WITH HOLD子句。如果一个游标在声明的时候没有指定WITH HOLD,那么它的所有资源(游标,锁,大对象数据类型或者LOB locators)都将在COMMIT或者ROLLBACK之后被释放。因此,如果需要在完成一个事务之后使用游标,就必须重新打开游标,并从第一行开始执行。如果定义了一个游标WITH HOLD,游标就会在事务之间保存它的位置和锁(lock)。需要明白的是,只有保证游标位置的锁被held了。
      锁(lock)是个数据库对象(a database object),我们用它来控制多个应用访问同一个资源的方式。而一个LOB locator使存储在本地变量中的4字节的值,程序可以用它来查到数据库系统中的LOB对象的值


A:定义了WITH HOLD的游标在COMMIT之后
       1.仍然保证是打开(open)的
       2.游标指向下一个满足条件的行之前
       3.在COMMIT语句之后只允许FETCH和CLOSE
       4.Positioned delete和positioned update只在同一事务中fetch的行上可用
       5.所有的LOB locators会被释放
       6.除了保存声明为WITH HOLD的游标位置的锁,其他锁都会释放
       7.当执行了数据修改语句或者含有WITH HOLD游标的修改语句被commit的时候
B:所有定义为WITH HOLD的游标在ROLLBACK之后:
       1.所有游标会被关闭
       2.所有在该事务中的锁会被释放
       3.所有的LOB locators会被freed

无论是否使用with hold与否,rollback将释放session中的游标。commit只释放不带with hold的游标。
以SqlServer为例:
当 SET CURSOR_CLOSE_ON_COMMIT 为 ON 时,该设置遵从 SQL-92 标准,在提交或回滚时关闭任何打开的游标。
当 SET CURSOR_CLOSE_ON_COMMIT 为 OFF 时,提交事务时不关闭游标.
不论CURSOR_CLOSE_ON_COMMIT如何设置, ROLLBACK时都是关闭游标,释放资源


解决方案:
可以利用save transaction的方法来控制ROLLBACK提交的空间.

 

DROP PROCEDURE TEST
GO
CREATE PROCEDURE TEST
AS 
BEGIN
	DECLARE @column NVARCHAR(20)

	DECLARE #T CURSOR FOR
	SELECT 'DOG' AS COLUMN1
	UNION ALL
	SELECT 'CAT'
	
	OPEN #T
	FETCH #T INTO @column
	
	BEGIN TRANSACTION

	WHILE(@@FETCH_STATUS = 0) 
	BEGIN
		SAVE TRANSACTION tran_save
		INSERT INTO TEST_TABLE (COLUMN1)
		SELECT @column + 'AA'

		IF @column = 'CAT'
		BEGIN
			PRINT 'COMMIT SAVE ' + @column + 'AA'		
		END
		ELSE
		BEGIN
			PRINT 'ROLLBACK SAVE ' + @column + 'AA'
			ROLLBACK TRANSACTION tran_save
		END

		FETCH #T INTO @column
	END
	CLOSE #T
	DEALLOCATE #T
	
	COMMIT
		
END

这样即可解决问题

      

 

分享到:
评论

相关推荐

    数据库管理与应用-3期(KC004) 任务5-3 事务与游标教学设计.docx

    教师会通过巡视、检查和评估学生的表现,给出参考解决方案,并讨论学生的解答,以此加深理解。 课堂总结时,教师会强调事务的整体性和游标的五步使用流程,帮助学生巩固知识。课后作业则会进一步扩展学生的实践能力...

    ORACLE游标中的多表UPDATE行锁讨论.pdf

    需要注意的是,行锁是在游标OPEN时开始,直到事务提交(COMMIT)或回滚(ROLLBACK)时结束,而不是在关闭游标时释放。如果有两个会话试图同时更新同一行,后一个会话会等待第一个会话完成其事务,防止出现死锁。 在...

    PYTHON常用库pymysql的使用,用于连接MySQL数据库

    `pymysql`支持Python 2.7及以上的版本,包括Python 3.x,这使得它成为Python开发环境下的跨版本数据库连接解决方案。 首先,让我们深入了解一下如何安装`pymysql`。通过Python的包管理工具`pip`,你可以简单地运行...

    Python + MySQL 学习项目.zip

    在本“Python + MySQL 学习项目”中,我们将探讨如何使用Python编程语言与MySQL数据库进行交互,以实现数据的存储、查询、更新和删除等基本操作。...实践中遇到的问题和解决方案将进一步增强你的问题解决能力。

    基于Python的SQLite数据库存储.zip

    Python是一种广泛使用的编程语言,尤其在数据处理和分析领域中占据重要地位。...这个主题的PDF文件应该包含详细的步骤、示例代码和可能遇到的问题及其解决方案,对于初学者和进阶者都是很好的学习资源。

    SqliteDB.rar_python sqlite

    SQLite数据库文件是自包含的,可以在文件系统中直接操作,非常适合小型项目或者作为开发阶段的数据存储解决方案。本示例将详细介绍如何使用Python进行SQLite数据库的读取操作。 首先,Python通过sqlite3模块与...

    MySQL-python-1.2.3.win-amd64-py2.7

    MySQL-python-1.2.3.win-amd64-py2.7是一个针对Python 2.7版本的MySQL数据库连接库,专为64位Windows操作系统设计。这个库,也称为`MySQLdb...然而,随着技术的发展,对于新项目,建议考虑使用支持Python 3的解决方案。

    Python库 | PyGreSQL-4.2.1-cp26-none-win32.whl

    **Python库PyGreSQL简介** PyGreSQL是一个Python接口,用于与PostgreSQL数据库进行交互。...通过正确安装和使用这个库,可以充分利用PostgreSQL的强大功能,为Python应用程序提供稳定、高性能的数据存储解决方案。

    Python库 | pyodbc-4.0.15-cp27-cp27m-win32.whl

    通过理解如何建立连接、执行SQL、处理结果和管理事务,你可以利用这个库在Python项目中构建高效的数据处理解决方案。在实际应用中,确保遵循最佳实践,如使用参数化查询和妥善处理错误,以提高代码的安全性和可靠性...

    pymssql-2.1.0.zip

    **Python与SQL Server的桥梁:pymssql-2.1.0** 在Python编程中,当我们需要与Microsoft ...在实际应用中,根据具体需求,结合其他库(如`pyodbc`)和ORM框架(如`SQLAlchemy`),可以构建出更健壮的数据库解决方案。

    MySQL-python

    对于那些没有安装C编译器的用户,MySQL-python 1.2.3的预编译Windows安装包提供了一个便捷的解决方案,可以直接在Python 2.7环境中运行,避免了编译过程。 Python 2.7和Python 3.x之间的主要区别在于语法、标准库...

    pymssql.py

    《Python中的pymssql:连接SQL数据库的利器》 在Python编程中,处理数据库是一项常见的任务,而pymssql正是一个强大的...通过实践和学习,你将能够利用这个库实现复杂的数据库操作,为你的项目带来更高效的解决方案。

    完整版 Python高级开发课程 高级教程 06 Python操作MySQL数据库.pptx

    此外,如果项目涉及分布式系统,可能还会学习到如何使用Python操作多个数据库实例,例如通过主从复制、分片或者分布式数据库解决方案。 在后续的课程中,你还将接触到Python操作MongoDB数据库,这是NoSQL数据库的一...

    SQLite数据库,sqlit3

    SQLite是一个开源、轻量级的嵌入式...以上是关于SQLite数据库的基本介绍,它在小型应用和嵌入式系统中尤其适用,提供了一种高效、可靠的数据存储解决方案。了解和掌握SQLite的使用,对于开发人员来说是一项重要的技能。

    sqlite一个轻巧的数据库 - 真功夫

    SQLite作为一个轻量级数据库解决方案,其简单易用、性能优异的特点使其成为许多应用程序的首选数据库。通过Python的PySQLite接口,开发者可以轻松地在代码中集成SQLite,进行高效的数据管理和操作。无论是构建桌面...

    神通数据库/MPP-Python解释器模块

    神通数据库(RDS)是一款由北京瑞斯康达科技发展股份有限公司开发的高性能、高可用性的分布式并行数据库系统,特别适用于大数据...在实际工作中,结合Python的生态系统,可以构建出高性能的数据处理和分析解决方案。

    oracle10G PPT

    Oracle 10G是Oracle数据库的一个重要版本,它在2003年发布,提供了许多增强功能和优化,以提高数据库性能、可用性和安全性...PPT中的内容可能会包含实例、最佳实践和解决方案,帮助你从理论到实践全面掌握这些知识点。

    SQLite3数据库封装

    它的设计目标是提供一个可移植、可靠且高效的数据库解决方案,尤其适用于移动设备和小型应用。在本“SQLite3数据库封装”主题中,我们将深入探讨如何将SQLite3的功能集成到你的项目中,以便进行高效的数据存储和检索...

    第14章 数据库编程.pptx

    `Connection`对象提供了多种方法,包括`execute()`用于执行SQL语句,`cursor()`返回游标对象,`commit()`用于提交事务保存数据,`rollback()`用于回滚事务,以及`close()`用于关闭连接。 在SQLite中,还可以自定义...

    数据库课程设计(python+mysql).zip

    8. **项目展示与文档**:最后,整理项目代码,编写项目报告,详细记录设计思路、实现方法和遇到的问题及解决方案。 在这个过程中,学生不仅会提升数据库理论知识,还将锻炼实际操作技能,为未来从事数据分析、后端...

Global site tag (gtag.js) - Google Analytics