我找不到在MySql存储过程中使用事务的最佳方法.ROLLBACK
如果有任何失败我想要:
BEGIN
SET autocommit=0;
START TRANSACTION;
DELETE FROM customers;
INSERT INTO customers VALUES(100);
INSERT INTO customers VALUES('wrong type');
COMMIT;
END
Run Code Online (Sandbox Code Playgroud)
1)autocommit=0
需要吗?
2)如果第二个INSERT
中断(当然它确实),第一个INSERT
不会回滚.程序只是继续下去COMMIT
.我怎么能阻止这个?
3)我发现我可以DECLARE HANDLER
,我应该使用这条指令还是有更简单的方法来说如果任何命令失败,存储过程应该ROLLBACK
也会失败?
DECLARE HANDLER
工作正常,但由于我有MySql版本5.1我不能使用RESIGNAL
.因此,如果发生错误,将不会通知来电者:
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
ROLLBACK;
-- RESIGNAL; not in my version :(
END;
START TRANSACTION;
Run Code Online (Sandbox Code Playgroud) 我有2个存储库,一个用于mongodb(DocumentRepository),另一个用于hibernate实体(EntityRepository)
我有一个简单的服务:
@Transactional
public doSomePersisting() {
try {
this.entityRepository.save(entity);
this.documentRepository.save(document);
}
catch(...) {
//Rollback mongoDB here
}
}
Run Code Online (Sandbox Code Playgroud)
是否可以在"// Rollback mongoDB here"行回滚mongoDB?我已经从实体部分回滚(Transactional annotation)
我刚刚开始学习Hibernate,并且我为每个事务使用以下模式(来自文档):
private Session session;
private Transaction transaction;
protected List selectAll(Class clazz) throws HibernateException {
List objects = null;
try {
session = MyHibernateHelper.getSessionFactory().openSession();
transaction = session.beginTransaction();
// SELECT ALL
objects = session.createCriteria(clazz).list();
transaction.commit();
} catch (HibernateException exc) {
if (transaction != null) transaction.rollback();
throw exc;
} finally {
session.close();
}
return objects;
}
Run Code Online (Sandbox Code Playgroud)
我可以接受每个操作都应该包含在一个事务中.但是select
,如果它失败,我觉得很奇怪也没必要回滚.
我想我可以安全地catch
从上面的例子中删除块.从任何只读操作.我对吗?
如果我们在以下调度中使用Timestamp Ordering进行并发控制:
我的TA说T2,T3,T5是Run和T4,T1是Rollback.我认为这是错误的.任何专家都可以帮助我们?(即,在此计划中哪个事务回滚和哪一个已完成?
更新:完成所有工作后的所有事务,提交.
所以在我的weblogic应用程序中,我们使用的是一些jtaWeblogicTransactionManager.有一些默认超时可以在注释中覆盖@Transactional(timeout = 60)
.我创建了一些无限循环来从db中读取正确超时的数据:
29 Apr 2018 20:44:55,458 WARN [[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'] org.springframework.jdbc.support.SQLErrorCodesFactory : Error while extracting database name - falli
ng back to empty error codes
org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Unexpected exception while enlisting XAConnection java.sql.SQLExceptio
n: Transaction rolled back: Transaction timed out after 240 seconds
BEA1-2C705D7476A3E21D0AB1
at weblogic.jdbc.jta.DataSource.enlist(DataSource.java:1760)
at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1645)
at weblogic.jdbc.wrapper.JTAConnection.getXAConn(JTAConnection.java:232)
at weblogic.jdbc.wrapper.JTAConnection.checkConnection(JTAConnection.java:94)
at weblogic.jdbc.wrapper.JTAConnection.checkConnection(JTAConnection.java:77)
at weblogic.jdbc.wrapper.Connection.preInvocationHandler(Connection.java:107)
at weblogic.jdbc.wrapper.Connection.getMetaData(Connection.java:560)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:331)
at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:366)
at org.springframework.jdbc.support.SQLErrorCodesFactory.getErrorCodes(SQLErrorCodesFactory.java:212)
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.setDataSource(SQLErrorCodeSQLExceptionTranslator.java:134) …
Run Code Online (Sandbox Code Playgroud) 需要一种优雅的方式将 Delta Lake 回滚到以前的版本。
我目前的方法如下:
import io.delta.tables._
val deltaTable = DeltaTable.forPath(spark, testFolder)
spark.read.format("delta")
.option("versionAsOf", 0)
.load(testFolder)
.write
.mode("overwrite")
.format("delta")
.save(testFolder)
Run Code Online (Sandbox Code Playgroud)
但这很丑陋,因为需要重写整个数据集。似乎一些元更新就足够了,不需要数据 I/O。有人知道更好的方法吗?
我有一个应用程序,通过c#中的批量复制类从我的数据库中复制.
发生异常时,我可以在sql server中回滚批量复制操作吗?
我正在使用visual studio 2010中的Database项目生成一个脚本来部署我的数据库(以及它的更改).这非常有效.
有没有办法让Visual Studio数据库项目生成回滚脚本以及部署脚本.
我不打算在部署时回滚事务; 但是说我部署它并且我的存储过程有一个忽略的性能问题,一周后出现,需要回滚到以前版本的数据库.
有没有办法在构建/部署时生成回滚脚本,这将撤消部署脚本所做的任何更改.
编辑:如果我们忽略我正在使用数据库项目:生成数据库的升级和降级路径有什么好方法?
这一代需要成为自动构建过程的一部分.
我已经看到许多不同的方法可以使用Git丢弃更改/恢复到之前的提交.我通常可以找出哪些适用于我的情况,但在这个过程中我对不同的方法感到很困惑.最近我试图撤消一些文件重命名,无论我多么努力地尝试git checkout
旧版本的文件,我仍然无法恢复旧文件.
我正在寻找澄清使用哪种方法和原因.以下是我对一些方法的理解.我意识到答案可能非常具有上下文性,但我想尝试找出哪些上下文需要哪种方法.
1)git checkout -- .
2)git stash save --keep-index
接下来git stash drop
3)git reset --hard
这是我目前对我的选择的理解.你对我的解释有什么改变吗?我也不确定何时使用git revert
代替上述命令.
来源帖子:
请考虑以下服务(默认情况下为事务性).玩家必须始终拥有一个帐户.没有至少一个相应帐户的玩家是错误状态.
class playerService {
def createPlayer() {
Player p new Player(name: "Stephen King")
if (!p.save()) {
return [code: -1, errors:p.errors]
}
Account a = new Account(type: "cash")
if (!a.save()) {
// rollback p !
return [code: -2, errors:a.errors]
}
// commit only now!
return [code: 0, player:p]
}
}
Run Code Online (Sandbox Code Playgroud)
我已经看过经验丰富的Grails开发人员的这种模式,当我告诉他们如果播放器的帐户创建因任何原因失败时,它不会回滚播放器,并且会使DB处于无效状态,他们会像我一样看着我我很生气,因为grails处理回滚玩家因为服务交易正确吗?
那么,作为一个SQL人,我寻找一种在grails中调用回滚的方法.没有一个.根据各种帖子,只有两种方法可以强制grails在服务中回滚:
.
DomainObject.withTransaction {status ->
//stuff
if (someError) {
status.setRollbackOnly()
}
}
Run Code Online (Sandbox Code Playgroud)
1.抛出未经检查的异常
1.1因此,我们必须抛出运行时异常以进行回滚.这对我来说是好的(我喜欢例外),但是这不会与我们拥有的grails开发人员凝聚在一起,他们将异常视为对Java的回归而且是不酷的.这也意味着我们必须改变应用程序当前使用其服务层的整个方式.
1.2如果抛出异常,则会丢失p.errors - 您将丢失验证详细信息.
1.3我们的新grails devs不知道unchecked和checked异常之间的区别,也不知道如何区分.这真的很危险.
1.4.使用.save(failOnError:true)我很喜欢使用它,但它并不适合所有地方.有时您需要在进一步检查之前检查原因,而不是抛出异常.它可以生成的异常是否始终检查,始终未选中,或者是否?即无论是什么原因导致failOnError AWLAYS回滚?没有人问我知道答案,这是令人不安的,他们使用盲目的信念来避免损坏/不一致的数据库.
1.5如果控制器调用服务A,调用服务B,然后调用服务C,会发生什么情况.服务A必须捕获任何异常并将格式良好的返回值返回给控制器.如果Service C抛出一个由服务A捕获的异常,那么将回滚服务Bs事务吗?这对于知道能够构建工作应用程序至关重要.
更新1:完成一些测试后,任何运行时异常,即使抛出并捕获到一些不相关的子调用,也会导致父进程中的所有内容都回滚.但是,在父会话中知道这种回滚已经发生并不容易 - 你需要确保如果你发现任何异常,你要么重新抛出,要么将一些通知传回给调用者以表明它已经失败了一种方式,其他一切将被回滚.
2. withTransaction …
rollback ×10
java ×3
hibernate ×2
spring ×2
apache-spark ×1
bcp ×1
branch ×1
c# ×1
commit ×1
database ×1
databricks ×1
delta-lake ×1
exception ×1
git ×1
git-reset ×1
grails ×1
mongodb ×1
mysql ×1
oracle ×1
spring-boot ×1
sql ×1
sql-server ×1
sqlbulkcopy ×1
transactions ×1