我有一个使用Hibernate连接数据库的JavaEE应用程序.在我的应用程序的某些部分,我调用了带有@Transactional
注释的方法.在某些情况下,我想回滚整个事务(外部服务方法调用和内部事务).在某些情况下,我想只回滚内部服务方法调用(即,回滚到内部方法开始时定义的保存点).
第一部分已经到位,但我对第二部分有疑问.当我执行以下操作时,我得到一个"UnexpectedRollbackException",消息"事务已回退,因为它已被标记为仅回滚".
@Service
public class OuterService{
@AutoWired
private InnerServcie innerService;
@Transactional
public void outer(){
try{
innerService.inner();
}catch(RuntimeException e){
//if i dont throw this up, it will give me the "UnexpectedRollbackException"
System.out.println("I cought a RuntimeException");
}
}
}
@Service
public class InnerServcie{
@Transactional
public void inner(){
//here we insert some data into db using hibernate
//but something goes wrong and an exception is thrown
}
}
Run Code Online (Sandbox Code Playgroud) 我们正在尝试自定义 User 模型和行为,但随后我们注意到,即使是默认的 Django 安装在通过 Django Admin 添加新用户时也会出现问题:
该问题甚至在其他 Django 版本中也会发生(在 Django 1.8和最新版本 Django 1.11.3 中尝试过)。令人惊讶的是,使用 SQLite 或 PostgreSQL 数据库时不会发生此问题。此外,通过$./manage.py createuser
和 以编程方式添加用户将起作用。admin
通过终端编辑现有用途(如先前创建的超级用户)也将起作用。Group 的 CRUD 机制按预期工作,因此只有Add User
视图会受到影响。
可能的故障点包括Django 核心(任何版本)、MySQL 二进制文件(捆绑在 XAMPP for Mac 中,也尝试过各种版本)或MySQL-Python连接器(版本 1.2.5)。类似的问题在这里,使用 Django 1.10和 MySQL。
复制步骤:
安装最新的 Django 版本:
$ pip install django
安装 Python-MySQL 驱动程序:
$ pip install MySQL-python
创建一个新项目:
$ django-admin.py startproject sandbox
在 MySQL 中创建一个新数据库并在其中设置 db …
现在,我们用于插入记录集的过程是这样的:
(并注意"记录集"意味着某人的记录以及他们的地址,电话号码或任何其他联合表).
我们应该做更像这样的事吗?
在与ORA-01555有一些问题并阅读一些Ask Tom文章(比如这篇文章)后,我正在考虑尝试第二个过程.当然,正如Tom指出的那样,开始新的交易是应该由业务需求定义的.第二个过程值得尝试,还是一个坏主意?
我有适用于各种数据库的通用 jdbc 代码。我有一些处理事务和保存点的 api。
问题是有些数据库需要你手动释放保存点
conn.releaseSavepoint(savepoint1)
Run Code Online (Sandbox Code Playgroud)
有些只是在您进行手动发布时抛出一个例外(最显着的是 Oracle)。
如何在运行时检查数据库是否具有自动保存点释放或是否需要手动执行。还有,我有一些不错的 api。我不想捕获异常,在这种情况下它很丑陋且容易出错。抛出的异常是java.sql.SqlException,而不是“FeatureUnsupportedException”之类的东西。因此,如果存在真正的错误并且我愚蠢地抓住了它,那么我可能会在整个交易过程中完全失败。
谢谢
我正在尝试将保存点与python 2.6中内置的sqlite3模块一起使用.每次我尝试释放或回滚保存点时,我总是收到一个OperationalError: no such savepoint
.我错过了什么?
python version: 2.6.4 (r264:75821M, Oct 27 2009, 19:48:32)
[GCC 4.0.1 (Apple Inc. build 5493)]
PySQLite version: 2.4.1
sqlite3 version: 3.6.11
Traceback (most recent call last):
File "spDemo.py", line 21, in <module>
conn.execute("release savepoint spTest;")
sqlite3.OperationalError: no such savepoint: spTest
Run Code Online (Sandbox Code Playgroud)
从这段代码:
import sys
import sqlite3
print 'python version:', sys.version
print 'PySQLite version:', sqlite3.version
print 'sqlite3 version:', sqlite3.sqlite_version
print
conn = sqlite3.connect('db_spDemo.db')
conn.isolation_level = "DEFERRED"
with conn:
conn.execute("create table example (A, B);")
with conn:
conn.execute("insert …
Run Code Online (Sandbox Code Playgroud) 我SQLite
的应用程序目前使用事务 - 既可以回滚也可以提高性能.我正在考虑用保存点替换所有交易.其原因是,应用程序是多线程的(是的,sqlite
配置是线程安全的),并且在某些情况下,事务可能由两个线程在同一时间开始(在同一分贝).
BEGIN
,COMMIT
,ROLLBACK
有SAVEPOINT xyz
,RELEASE SAVEPOINT xyz
,ROLLBACK TO SAVEPOINT xyz
?Ora-01086:保存点未建立或无效.KRD_UPD_BORCTAHSILATYAP_SP此SP抛出错误.当我在下面测试这个循环时,我得到错误:ora-01086
通常它在不调用外部sp的情况下工作,我用内联错误测试它并且我回滚到保存点.我错过了什么?
FOR rec IN (...records.....
)
LOOP
SAVEPOINT odemeIslemiBaslangic;
BEGIN
CASE rec.prosedur_ad
WHEN 'KRD' THEN
KRD_UPD_BORCTAHSILATYAP_SP(rec.musterino, rec.urundegeri, rec.taksitno, v_MuhasebeReferans, v_IslemReferans, v_Tarih);
IF v_MuhasebeReferans IS NOT NULL THEN
v_SonucKd := 10;
v_Aciklama := 'Ba?ar?l? i?lem';
ELSE
v_SonucKd := 9;
v_Aciklama := 'Borç bulunamad?';
END IF;
END CASE;
cll_ins_tahsilatislem_sp(p_odemeno => rec.odemeno,
p_islemtarihi => v_Tarih,
p_musterino => rec.musterino,
p_urundeger => rec.urundegeri,
p_islemref => v_IslemReferans,
p_muhasebesubekd => rec.sube_kd,
p_muhaseberef => v_MuhasebeReferans,
p_aciklama => v_Aciklama,
p_sonuc => v_SonucKd,
p_kayityapan => v_KayitYapan,
p_kayittrxkod => v_KayitTrxKod); …
Run Code Online (Sandbox Code Playgroud) 我有一个 JDBC 代码,其中存在多个Savepoints
;像这样的东西:
1st insert statement
2nd insert statement
savepoint = conn.setSavepoint("S1");
1st insert statement
2nd update statement
savepoint = conn.setSavepoint("S2");
1st delete statement
2nd delete statement
savepoint = conn.setSavepoint("S3");
1st insert statement
2nd delete statement
savepoint = conn.setSavepoint("S4");
Run Code Online (Sandbox Code Playgroud)
现在在 catch 块中,我捕获异常并检查异常是否Savepoint
存在null
;如果是,则回滚整个连接,否则回滚直到Savepoint
. 但我不明白Savepoint
我要回滚到哪一步。
如果我将所有保存点名称更改为“S1”可以吗?在这种情况下,我如何了解有多少收银机Savepoint
正确工作?
请告知如何理解直到Savepoint
正确执行了哪些工作?
我有hsqldb(在内存中)的集成测试,现在我需要在我的测试中设置保存点,在BaseTest类中,如何在测试中设置保存点(hsqldb(内存中))?
BaseTest:
@ContextConfiguration(classes = {TestConfig.class})
public class BaseTest {
@Before
public void savePoint() {
//set savepoint - How can do it this?
}
@After
public void rollBackToSavePoint() {
//roll back to savepoint - How can do it this?
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试:
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest extends BaseTest {
@Test
public void test1() {
...
}
}
Run Code Online (Sandbox Code Playgroud)
TestConfig:
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
@Configuration
@EnableJpaRepositories("database.dao")
@ComponentScan(basePackageClasses = { MyServiceImpl.class})
@EntityScan({"database.model"})
@Import({DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class})
public class TestConfig {
...
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试了解 SQLite 中的保存点和事务。我在表/数据库上有以下命令,我正在使用保存点。
SAVEPOINT aaa;
RELEASE aaa;
BEGIN;
Run Code Online (Sandbox Code Playgroud)
现在,如果我一次执行上述所有语句,它会抛出一个错误,说A transaction cannot be started inside another transaction
. 如果我一次运行一个,它工作正常。如果我运行前两个 Savepoint 和 release 命令并尝试通过执行Begin
. 它再次抛出与以前相同的错误。
这里的链接说
如果 SAVEPOINT 命令在 SQLite 处于自动提交模式时(即在事务之外)发出,则将启动标准自动提交 BEGIN DEFERRED TRANSACTION。但是,与大多数命令不同,自动提交事务在 SAVEPOINT 命令返回后不会自动提交,使系统处于打开的事务中。自动事务将保持活动状态,直到原始保存点被释放,或者外部事务被显式提交或回滚。`
那么,Release Savepoint 命令之后是否一定需要 Commit 或 Rollback 命令呢?不release
命令提交并允许我们使用BEGIN
?