一个存储过程事务是否可以看成一个完整的事务

清除回答草稿
&&&您需要以后才能回答,未注册用户请先。在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
问题对人有帮助,内容完整,我也想知道答案
问题没有实际价值,缺少关键内容,没有改进余地
你好,业务需要,开发了一个分区的函数,实现分区表的自动分区(range分区),
现在问题是数据表有7000张,每到月中执行一次,扩展15天的分区,现在测试的情况是函数效率很低,定位到问题在greenplum中,把函数/存储过程当成了一整个事务,必须全部执行完毕才提交吗?
有没有办法做到没循环执行一个sql(alter table add partition,就提交一次)
附详细函数代码,不胜感激
-- Function: dwdb.proc_add_partition()
-- DROP FUNCTION dwdb.proc_add_partition();
CREATE OR REPLACE FUNCTION dwdb.proc_add_partition()
RETURNS void AS
DECLARE V_SQL1 TEXT;
V_TABLENAME
V_TABLEDATE
START_TIME_NUMERIC NUMERIC;
START_END_NUMERIC
END_TIME_NUMERIC
START_TIME_DATE
TIMESTAMP WITHOUT TIME ZONE;
END_TIME_DATE
TIMESTAMP WITHOUT TIME ZONE;
C_CUR1 CURSOR FOR
SELECT SCHEMANAME || '.' || TABLENAME,
MAX(TO_CHAR((SUBSTR(REPLACE(PARTITIONNAME, 'p', ''), 1, 4) || '-' ||
SUBSTR(REPLACE(PARTITIONNAME, 'p', ''), 5, 2) || '-' ||
SUBSTR(REPLACE(PARTITIONNAME, 'p', ''), 7, 2))
::TIMESTAMP + INTERVAL '1 DAY',
'YYYYMMDD') ::NUMERIC)
FROM PG_PARTITIONS
WHERE SCHEMANAME IN ('dwdb')
AND PARTITIONNAME LIKE '%p%'
AND PARTITIONNAME NOT LIKE '%-%'
AND LENGTH(PARTITIONNAME) = 9
--AND TABLENAME = 'dw_f_re_st_volte_mgcf_h'
GROUP BY SCHEMANAME || '.' || TABLENAME;
OPEN C_CUR1;
FETCH C_CUR1
INTO V_TABLENAME, V_TABLEDATE;
IF NOT FOUND THEN
START_END_NUMERIC
:= TO_CHAR((SUBSTR(V_TABLEDATE, 1, 4) || '-' ||
SUBSTR(V_TABLEDATE, 5, 2) || '-' ||
SUBSTR(V_TABLEDATE, 7, 2))
::TIMESTAMP + INTERVAL '1 DAY',
'YYYYMMDD') ::NUMERIC;
START_TIME_NUMERIC := V_TABLEDATE;
START_TIME_DATE
:= (SUBSTR(START_TIME_NUMERIC, 1, 4) || '-' ||
SUBSTR(START_TIME_NUMERIC, 5, 2) || '-' ||
SUBSTR(START_TIME_NUMERIC, 7, 2)) ::TIMESTAMP;
END_TIME_DATE
:= START_TIME_DATE + INTERVAL '1 DAY';
END_TIME_NUMERIC := TO_CHAR((SUBSTR(V_TABLEDATE, 1, 4) || '-' ||
SUBSTR(V_TABLEDATE, 5, 2) || '-' ||
SUBSTR(V_TABLEDATE, 7, 2))
::TIMESTAMP + INTERVAL '1 DAY',
'YYYYMMDD') ::NUMERIC;
EXIT WHEN START_TIME_NUMERIC &= START_END_NUMERIC;
V_SQL1 = '
ALTER TABLE ' || V_TABLENAME || ' ADD PARTITION P' || START_TIME_NUMERIC || ' START (' || START_TIME_NUMERIC || ')
END (' || END_TIME_NUMERIC || ');
EXECUTE V_SQL1;
--INSERT INTO ST_PROCESS_LOG (REMARK) VALUES(V_SQL1);
START_TIME_NUMERIC := TO_CHAR((SUBSTR(START_TIME_NUMERIC, 1, 4) || '-' ||
SUBSTR(START_TIME_NUMERIC, 5, 2) || '-' ||
SUBSTR(START_TIME_NUMERIC, 7, 2))
::TIMESTAMP + INTERVAL '1 DAY',
'YYYYMMDD') ::NUMERIC;
START_TIME_DATE
:= START_TIME_DATE + INTERVAL '1 DAY';
END_TIME_NUMERIC
:= TO_CHAR((SUBSTR(START_TIME_NUMERIC, 1, 4) || '-' ||
SUBSTR(START_TIME_NUMERIC, 5, 2) || '-' ||
SUBSTR(START_TIME_NUMERIC, 7, 2))
::TIMESTAMP + INTERVAL '1 DAY',
'YYYYMMDD') ::NUMERIC;
END_TIME_DATE
:= END_TIME_DATE + INTERVAL '1 DAY';
WHEN OTHERS THEN
LANGUAGE plpgsql VOLATILE;
ALTER FUNCTION dwdb.proc_add_partition()
答案对人有帮助,有参考价值
答案没帮助,是错误的答案,答非所问
这个据我所知可能不行。
变通的办法是,这样的逻辑,用 python 实现也不复杂。如果实在想用 sql 做接口,那就用外部表去调用写好的 python 程序。
CREATE EXTERNAL WEB TABLE proc_add_partition (result int) EXECUTE '/path/to/python/code' ON MASTER;
分享到微博?
关闭理由:
删除理由:
忽略理由:
推广(招聘、广告、SEO 等)方面的内容
与已有问题重复(请编辑该提问指向已有相同问题)
答非所问,不符合答题要求
宜作评论而非答案
带有人身攻击、辱骂、仇恨等违反条款的内容
无法获得确切结果的问题
非开发直接相关的问题
非技术提问的讨论型问题
其他原因(请补充说明)
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。事务与存储过程之事务管理 - 简书
事务与存储过程之事务管理
事务的概念现实生活中,人们经常会进行转账操作,转账可以分为两部分来完成,转入和转出,只有这两个部分都完成才认为转账成功。在数据库中,这个过程是使用两条语句来完成的,如果其中任意一条语句出现异常没有执行,则会导致两个账户的金额不同步,造成错误。为了防止上述情况的发生,MySQL中引入了事务,所谓事务就是针对数据库的一项操作,它可以由一条或多条SQL语句组成,同一个事务的操作具备同步的特点,如果其中由一条语句无法执行,那么所有的语句都不会执行,也就是说,食物中的语句要么都执行,要么都不执行。在数据库中使用事务是,必须先开启事务,开启事务的语句具体如下START TRANSACTION;上述语句就用于开启事务,事务开启之后就可以执行SQL语句,SQL语句执行成功后,需要使用相应的语句提交事务,提交事务的语句具体如下:COMMIT;需要注意的是,在MySQL中直接书写的SQL语句都是自动提交的,而事务中的操作语句都需要使用COMMIT语句手动提交,只有事务后其中的操作才会生效.如果不想提交当前事务,还可以使用相关语句取消事务(也称回滚),具体语句如下:ROLLBACK;需要注意的是,ROLLBACK语句只能针对未提交的事务执行回滚操作,已提交的事务是不能回滚的.通过上述的讲解,读者对事务有了一个简单的了解,为了让读者更好的学习事务,接下来通过一个转账的案例来掩饰如何使用事务。在演示之前,首先需要创建一个当天数据库day1116,并在数据库中创建一个account表,插入相应的数据,SQL语句具体如下:
CREATE TABLE account(
id INT primary key auto_increment,
name VARCHAR(40),
money FLOAT
INSERT INTO account (name , money) VALUES ('a' , 1000);
INSERT INTO account (name , money) VALUES ('b' , 1000);
为了验证数据是否添加成功,可以使用SELECT语句查询account表中的数据,查询结果截图!我们接下来使用事务来演示如何实现转账功能。例:首先开启一个事务,然后通过UPDATE语句将a账户的100元钱转给b账户,最后提交事务,具体语句如下:
START TRANSACTION;
UPDATE account SET money=money-100 WHERE name='a';
UPDATE account SET money=money+100 WHERE name='b';
上述语句执行成功以后,可以使用SELECT语句来查询account表中的余额,查询结果截图!从查询结果可以看出,通过事务成功的完成了转账功能,需要注意的是,上述两条UPDATE语句中,如果任意一条语句出现错误,就会导致事务不会提交,这样一来,如果再提交事务之前出现异常,事务中未提交的操作就会被取消。因此就可以保证事务的同步性。事务有很严格的定义,他必须同时满足4个特性。即原子性,一致性,隔离性,持久性,也就是人们俗称的ACID标准,接下来就针对这4个特性进行讲解,具体如下。1、原子性原子性是指事务必须被认为是一个不可分割的单元,只有事务中所有的数据库操作都执行成功,才算整个事务执行成功,事务中如果有任何一个SQL语句执行失败,已经执行成功的SQL语句也必须撤销,数据库的状态退回到执行事务前的状态。这在一些关键系统中尤其重要,现实世界的应用程序(如金融系统)执行数据输入或更新,必须保证不出现数据丢失或者数据错误,以保证数据安全性。2、一致性一致性是指事物将数据库从一种状态转变为下一种一致的状态。例如,在表中有一个字段为姓名,具有唯一约束,即姓名不能重复,如果一个事物对姓名进行了修改,使姓名变得不唯一了,这就破坏了事务的一致性要求,如果事务中的某个动作失败了,系统可以自动撤销事务,返回初始化的状态。在MySQL当中,一致性主要由MySQL的日至机制处理,它记录了数据库的所有变化,为事务恢复提供了跟踪记录。如果系统在事务处理中间发生错误,MySQL恢复过程将使用这些日志来发现是否已经完全成功的执行,否则需要返回,因此一致性属性保证了数据库从不返回一个未处理完的事务。3、隔离性隔离性还可以成为并发控制,可串行化,锁等,当多个用户并发访问数据库时,数据库为每一个用户开起的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。4、持久性事物一旦提交,其所做的修改就会永久保存到数据库中。即使数据库发生故障也不应该对其有任何影响。需要注意的是,事物的持久性不能做到百分之百的持久。只能从事物本身的角度来保证永久性,而一些外部原因导致数据库发生故障,如硬盘损坏,那么所有提交的数据可能都会丢失。需要注意的是,针对事物的四个特性有个简单的印象就可以了,不必太过斟酌,事物的操作才是重点掌握的内容。事务的提交现实生活中许多操作都是需要用户确认的,例如在删除一个文档是当选择删除时,会弹出一个提示对画框。包含两个按钮“确定”和“取消”。如果单击“确定”按钮该文档才会删除。同理,在数据库中,有些命令的使用也是需要被确认的,例如事务中的操作就需要用户确认。当用户确认提交后,事务中的操作才会执行成功,这个过程就是手动提交的过程。接下来针对事物的提交进行详细的讲解。为了说明事物的提交方式为手动提交,接下来。在上一节的基础上进行操作。这时的a账户有900元钱b账户有1100元钱,开启一个事务,使用UPDATE语句实现由b账户向a账户转100元钱的转账功能,具体语句如下:
START TRANSACTION;
UPDATE account SET money=money+100 WHERE name='a';
UPDATE account SET money=money-100 WHERE name='b';
上述语句执行成功后,可以使用SELECT语句来查询account表中的余额,查询结果截图。从上述结果可以看出,在事务中实现了转账功能。此时,退出数据库然后重新登录,并查询数据库中各账户的余额信息,查询结果截图。从上述结果可以看出事务中的转账操作没有成功,这是因为在事务中转账成功后,还没有提交事务就退出数据库了,由于事务中的语句不能自动提交,因此当前的操作就被自动取消了,接下来再次执行上述语句,然后使用commit的语句来提交。具体语句如下:
START TRANSACTION;
UPDATE account SET money=money+100 WHERE name='a';
UPDATE account SET money=money-100 WHERE name='b';
上述语句执行成功后,退出数据库然后再重新登录,使用SELECT语句查询数据库中各账户的余额,信息查询结果截图。从上述结果可以看出事物中的转账操作成功了。需要注意的是,由于事务中的操作都是手动提交的,因此在操作完事务时,一定要使用COMMIT语句提交事务,否则是误操作会失败。事务的回滚在操作一个事物时,如果发现当前事务中的操作是不合理的,此时只要还没有提交事务就可以通过回滚来取消当前事务,接下来就针对事务的回滚进行详细的讲解。这时a账户有1000元,b账户有1000元,开启一个事物,通过update语句将a账户的100元转给b账户,具体语句如下。
START TRANSACTION;
UPDATE account SET money = money - 100 WHERE name = 'a';
UPDATE account SET money = money + 100 WHERE name = 'b';
上述语句执行成功后,使用SELECT语句查询a账户和b账户的金额查询结果如下:a--900
,b--1100从上述结果可以看出,a账户成功给b账户转账100元前,如果此时a账户想给b账户转账了,由于事务还没有提交,就可以将事务回滚,具体语句如下:ROLLBACK;ROLLBACK语句执行成功后,再次使用SELECT语句查询数据库,查询结果如下:a--1000
,b--1000从查询结果可以看出,数据库中a账户的金额和b账户的金额还是1000元,并没有完成转账的功能,因此可以说明当前事务中的操作取消了。
幻读(PHANTOM READ)又被称为虚读,是指在一个事务内两次查询中数据条数不一致,幻读和不可重复读有些类似,同样是在两次查询过程中,不同的是,幻读是由于其他事物做了插入记录的操作,导致记录数有所增加。 例如,银行在做统计报表时统计account表中所有用户的总额时,此...
一、什么是事务 逻辑上的一组操作, ,要不全部失败,要不全部成功。 MySql的事务管理 在事务管理中执行sql,使用数据库内临时表保存,在没有进行事务提交或者回滚之前,其它用户无法看到事务操作的结果 SQL语言中只有DML才能被事务管理(insert/update/del...
百战程序员_ Java1573题 QQ群:034603 掌握80%年薪20万掌握50%年薪10万 全程项目穿插, 从易到难,含17个项目视频和资料持续更新,请关注www.itbaizhan.com 国内最牛七星级团队马士兵、高淇等11位十年开发经验专...
MySQL技术内幕:InnoDB存储引擎(第2版) 姜承尧 第1章 MySQL体系结构和存储引擎 && 在上述例子中使用了mysqld_safe命令来启动数据库,当然启动MySQL实例的方法还有很多,在各种平台下的方式可能又会有所不同。 && 当启动实例时,MySQL数据库...
江湖传说:不了解数据库事务的程序员不是一个好的DBA。阅遍网上无数关于数据库事务的文章,都感觉云里雾里,不知所云。于是乎拍案而起,麻蛋,还是自己写吧。最后便有了这篇文章,它试图用通俗的文字来说明单机事务的ACID特性及其大致的实现原理。 一、什么是事务? 数据库事务(简称:...
在很久很久之前,我们从春秋扯起。
这是一个阴谋时代,又是一个改变了中国格局的时代。
首先呢,有个周天子,他开始把商打死了,打的屁滚尿流。可是时代变了,这个可能脑子缺了根弦,所以就导致了一个大笑话,大家也都听过——就是周幽王烽火戏诸侯。周天子为了博得美人一笑,所以莫名其...
赵融轩放何纯熙出门的时候,心里是忐忑的,他觉得以樊胜美这种在染缸里混大的女人,有一千种办法可以哄得他的纯熙上当。但他还是放她出门,是实在不忍心再禁锢她了,也算是给自己一个放了她的理由吧。没想到何纯熙回来的时候,真的垂头丧气,看样子樊胜美是承认了此事,这倒大大出乎他的意料。他...
(文 | 毛叶) “新闻快讯:今天下午A市公交车司机集体罢工,导致路面堵塞,通行条件受影响,请各位市民提前做好出行计划。” 苏雅看着手机里的消息,轻轻叹了一口气。车站的人越来越多,每个人都在等待着能把自己带回家的那一辆公交车,尽管身体疲惫,但是心里怀着期待。只可惜今天那辆车...MySQL技术内幕 InnoDB存储引擎 344页.
原来看过这段,总而言之,就是MySQL不要在存储过程中控制事务.
当时没有仔细看细节,只是记住了一个结论.
毕竟都21世纪了.还有用存储过程的?
但是..#(×&%¥×&@……&……#@&
以如下过程为例.
drop&table&&&
drop&procedure&pCreateN&&
create&table&nums(id&int&not&null&primary&key);&&
delimiter&$$&&
create&procedure&pCreateNums(cnt&int)&&
&&&&start&transaction;&&
&&&&insert&into&nums(id)&values(cnt+rand()*100);&&&&&&
&&&&insert&into&nums(id)&values(cnt);&&
&&&&commit;&&
delimiter&;&&
call&pCreateNums(10);&&
call&pCreateNums(10); &
连续调用两次过程,会触发主键冲突的异常.
最后的commit没有执行,第二个过程的事务并未完成.
这时,需要上层调用的程序,进行事务的提交或者回滚.
当然,也可以定义一个Handler进行异常处理.
drop&table&&&
drop&procedure&pCreateN&&
create&table&nums(id&int&not&null&primary&key);&&
delimiter&$$&&
create&procedure&pCreateNums(cnt&int)&&
&&&&declare&exit&handler&for&sqlexception&rollback;&&
&&&&start&transaction;&&
&&&&insert&into&nums(id)&values(cnt+rand()*100);&&&&&&
&&&&insert&into&nums(id)&values(cnt);&&
&&&&commit;&&
delimiter&;&&
call&pCreateNums(10);&&
call&pCreateNums(10);&
第一个过程执行成功,第二个过程触发异常处理自动回滚
但是,上层的JAVA程序对于这一切,都透明了..
他后续的工作怎么处理?
缓存是否更新?分布式架构下,任务还继续吗?给客户端返回什么?
所以,过程和JAVA程序还得约定异常的类型.
drop&table&&&
drop&procedure&pCreateN&&
create&table&nums(id&int&not&null&primary&key);&&
delimiter&$$&&
create&procedure&pCreateNums(cnt&int)&&
&&&&declare&exit&handler&for&sqlexception&begin&rollback;select&-1;end;&&
&&&&start&transaction;&&
&&&&insert&into&nums(id)&values(cnt+rand()*100);&&&&&&
&&&&insert&into&nums(id)&values(cnt);&&
&&&&commit;&&
&&&&select&1;&&
delimiter&; &
这样约定异常的常量,把异常处理,自己又实现了一遍.
MSSQL 可以自动回滚事务,并且会抛出异常,上层JAVA开发可以捕获这个异常.
但是MySQL还是做不到的.
所以事务控制最好由程序端完成.
drop&table&&&
drop&procedure&pCreateN&&
create&table&nums(id&int&not&null&primary&key);&&
delimiter&$$&&
create&procedure&pCreateNums(cnt&int)&&
&&&&start&transaction;&&
&&&&insert&into&nums(id)&values(cnt+rand()*100);&&&&&&
&&&&insert&into&nums(id)&values(cnt);&&
delimiter&;&
JAVA程序调用过程之前,开启事务,然后调用过程,根据过程的执行情况,提交或者回滚.
&&&回复&&&:
北京盛拓优讯信息技术有限公司. 版权所有 京ICP备号 北京市公安局海淀分局网监中心备案编号:10
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员事务与存储过程是什么关系_百度知道
事务与存储过程是什么关系
答题抽奖
首次认真答题后
即可获得3次抽奖机会,100%中奖。
来自知道合伙人认证行家
健身类行家
采纳数:145432
获赞数:631368
事务中可以有存储过程 存储过程中也可以有事务 事务是一系列的对数据库的操作,这些操作包括存储过程,更改语句及其它操作。开始语句是BEGIN TRANSACTION (事务开始),结束语句有两种,一个是ROLLBACK--回滚,一个是--commit提交事务的所有操作。 存储过程是实现一定功能的语句组成的程序段。可以包括事务,也可以在某事务当中。 这是一个包括一个事务处理过程的存储过程,并且在事务中也包括另一个存储过程的操作: CREATTE PROCEDURE MYPROCEDURE AS BEGIN TRANSACTION--开始一个事务 UPDATE TABLENAME SET ABC='DEF' WHERE ......--操作 EXEC OTHERPROCEDURE '参数' --事务中包括的存储过程 IF @@ERROR&0--操作如果失败 BEGIN ROLLBACK TRANSACTION--回滚 RAISERROR('更改数据失败!',16,1)--向前台报错 RETURN--返回,不再继续执行 END ELSE COMMIT TRANSACTION--操作成功,确认所作修改 GO
为你推荐:
其他类似问题
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 sqlserver存储过程 的文章

 

随机推荐